Index of element in list in Haskell - list

How can I get the index of the element I am at in haskell when I am using map ?
For example I have this list l = "a+bc?|(de)*fg|h" and I want to know the exact index of the element I am at when I use the map or scanl function.

Amending Nikita Volkov's answer, you can use a function such as:
-- variant of map that passes each element's index as a second argument to f
mapInd :: (a -> Int -> b) -> [a] -> [b]
mapInd f l = zipWith f l [0..]

First of all, if you need an index when processing a list it is a certain sign that you're implementing a suboptimal algorithm, because list is not an index-based structure like array. If you need to deal with indexes you better consider using a vector instead.
Concerning your actual question, you can pair the items of your list with incrementing ints with the following code and then map over the result:
Prelude> zip [0..] "a+bc?|(de)*fg|h" :: [(Int, Char)]
[(0,'a'),(1,'+'),(2,'b'),(3,'c'),(4,'?'),(5,'|'),(6,'('),(7,'d'),(8,'e'),(9,')'),(10,'*'),(11,'f'),(12,'g'),(13,'|'),(14,'h')]

Related

F# return list of list lengths

I am to use combinators and no for/while loops, recursion or defined library functions from F#'s List module, except constructors :: and []
Ideally I want to implement map
I am trying to write a function called llength that returns the list of the lengths of the sublists. For example llength [[1;2;3];[1;2];[1;2;3]] should return [3;2,3]. I also have function length that returns the length of a list.
let Tuple f = fun a b -> f (a, b)
let length l : int =
List.fold (Tuple (fst >> (+) 1)) 0 l
currently have
let llength l : int list =
List.map (length inner list) list
Not sure how I should try accessing my sublists with my restraints and should I use my other method on each sublist? any help is greatly appreciated, thanks!
Since this is homework, I don't want to just give you a fully coded solution, but here are some hints:
First, since fold is allowed you could implement map via fold. The folding function would take the list accumulated "so far" and prepend the next element transformed with mapping function. The result will come out reversed though (fold traverses forward, but you prepend at every step), so perhaps that wouldn't work for you if you're not allowed List.rev.
Second - the most obvious, fundamental way: naked recursion. Here's the way to think about it: (1) when the argument is an empty list, result should be an empty list; (2) when the argument is a non-empty list, the result should be length of the argument's head prepended to the list of lengths of the argument's tail, which can be calculated recursively. Try to write that down in F#, and there will be your solution.
Since you can use some functions that basically have a loop (fold, filter ...), there might be some "cheated & dirty" ways to implement map. For example, via filter:
let mymap f xs =
let mutable result = []
xs
|> List.filter (fun x ->
result <- f x :: result
true)
|> ignore
result |> List.rev
Note that List.rev is required as explained in the other answer.

Filter for element in a list of lists in Haskell

I built a list of this structure:
[(Interger, Double)]
The List was created by using a zip over a list of Integers and a list of Doubles of exactly the same size.
Now I want to filter the list for Doubles that are either <18.5 or >25. The problem I have is I can't access the Doubles to use them in the filter function.
It's probably easy but I'm a bloody noob in this language. I googled around a lot and read some other threads but I didn't find an answer.
I got:
filter (<18.5) listexpression
So what I'm struggling with is that listexpression. It's easy if it's a list of single values. I could filter before zipping but then I can't connect the data from the filtered list to the other unfiltered List anymore.
Edit: I forgot to mention. It's a worksheet. We were asked to build filter and map functions ourselves and are not allowed to use any additions to the basic Haskell. Meaning no imports are allowed.
You can do something like this:
Prelude> filter (\p -> (snd p) < 18.5 || (snd p) > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
The lambda function passed to filter, namely
(\p -> (snd p) < 18.5 || (snd p) > 25)
says that for every p, the second element of p must be less than 18.5 or over 25.
Alternatively, you could write it like this
Prelude> filter (\(_, f) -> f < 18.5 || f > 25) [(1, 2.3), (1, 20.0)]
[(1,2.3)]
Here the function says that for any pair whose first value doesn't matter and the second one is f, f must be less than 18.5 or over 25.
Glad to see Ami Tavory's answer solved your problem.
But under that answer, you commented:
I tried accessing it with a combination of (!!) but that didn't work.
With the insight of a teaching assistant [:D], I guess you confused list with tuple in Haskell.
zip returns a list of tuple, whereas (!!) take a list as (the first) argument (hence (!!1) take a single list argument), so (!!1) can't be applied to elements of the list returned by zip, which are of type tuple.
Prelude> :t zip
zip :: [a] -> [b] -> [(a, b)]
Prelude> :t (!!)
(!!) :: [a] -> Int -> a
Prelude> :t (!!1)
(!!1) :: [a] -> a
And you've known that fst and snd are applied to tuple.
Prelude> :t fst
fst :: (a, b) -> a
Prelude> :t snd
snd :: (a, b) -> b
A compact version using point free style would be
filter ((>18.5).snd) listexpression
This uses the function composition operator ., which reads as: First apply the snd function to a tuple from the list to extract the 2nd value, then apply the comparison to 18.5 to this value.
Just for a variety and some additional information which won't bite...
In Haskell the list type is an instance of Monad class. So a list operation like filter can simply be implemented by a monadic bind operator.
*Main> [(1,2.3),(3,21.2),(5,17.1),(4,24.4)] >>= \t -> if snd t < 25 && snd t > 18.5 then [t] else []
[(3,21.2),(4,24.4)]
Monad is all about handling the contained data in a sequential manner. In the list monad the contained data is the value within the list itself. So the bind operator can be very handy to access to contained values (tuples) of the monadic value (the list of tuples) in a sequential manner.
(>>=) :: Monad m => m a -> (a -> m b) -> m b
The type signature of the monadic bind operator states that it takes a monad type value m a as the first argument (the list of tuples here) and a function as the second argument which takes a pure value and returns a monadic value (takes a tuple and returns a tuple in a list or an empty list in this case).
\t -> if snd t < 25 && snd t > 18.5 then [t] else []
It's critical to understand how and why the list items are applied one by one to the provided function. An entire list is one monadic value and the contained values those accessed by the bind operator are passed to the provided a -> m b (take a pure value and return monadic value) type function. So all of the list items those applied to this function become a monadic value ([t] if condition satisfies or [] if it fails), are then concatenated by the bind operator to form one monadic return value (in this case a list of tuples those satisfy the condition which is implemented in the lambda function).
This monadic operation can also be implemented with the do notation
do
t <- [(1,2.3),(3,21.2),(5,17.1),(4,24.4)]
if snd t < 25 && snd t > 18.5 then return t else []
[(3,21.2),(4,24.4)]
Of course this terribly resembles the list comprehensions which is in fact a syntactical sugar to the monadic list operations. So lets implement it for a final time by using the list comprehensions.
*Main> [t | t <- [(1,2.3),(3,21.2),(5,17.1),(4,24.4)], snd t < 25 && snd t > 18.5]
[(3,21.2),(4,24.4)]

Obtaining Values from an Array

I am incredibly new to Haskell, and I am having trouble with some homework. I do not understand how to properly take in an array, and use the data with in it.
for example in java I would have something like
int[] arr = {...};
arr[0];
arr[1];
In my Haskell problem I have
dot :: [Float] -> [Float] -> Float
-- enter code here
I can not find a way to use the data inside the float array. My professors example for this problem uses Vectors, but we have to use a [Float]
I'm not asking for anyone to do the problem, just an explanation on how to use the array.
This is technically speaking not an array, but a (linked-)list. That is something different. A list is defined as:
data [a] = [] | (a:[a])
So it is a data-type that has two constructors:
the empty list [] which is used to signal the end of a list; and
the cons that has two elements: an a (the item) and a reference to the tail (a [a]).
Now that we know that you can use pattern matching to extract elements (and do tests). For instance in the following function:
head :: [a] -> a
head (x:_) = x
Here head expects to see a cons construct and it extracts the head (the element of the first node) and returns that. Or for instance:
second :: [a] -> a
second (_:(x:_)) = x
here again you use pattern matching to extract the second element.
Another way to obtain elements is using the (!!) :: [a] -> Int -> a. operator. You can obtain the i-th element (zero-based), by using:
list!!i
which is equivalent to list[i] in Java semantically. Mind however that - as said before - these are linked lists, so obtaining the i-th element requires O(i) computational effort. Although this may look like a detail it can become a bit dramatic when you want to fetch an object with a large index. Furthermore since (!!) is called, you are less certain there is such element: you have not that much guarantees that the list is indeed long enough. It is therefore wise to use pattern matching and look for clever ways to exploit the linked list data structure.
For your example for the dot product, you can for instance first use pattern matching like:
dot (x:xs) (y:ys) = ...
and so you have extracted the heads x and y from the lists. And then you can multiply them and add them to the dot product of the remainder of the list:
dot (x:xs) (y:ys) = x*y + dot xs ys
now you only still need to define base case(s) like for instance:
dot [] [] = 0.0
so putting it all together:
dot :: [Float] -> [Float] -> Float
dot [] [] = 0.0
dot (x:xs) (y:ys) = x*y + dot xs ys

How to count how many elements are in a list?

I know about the length function, but if I have a list such as [(1,2),(2,3),(3,4)] and try to use length it does not work. I tried to concatenate but that doesn't help. Any idea how?
While the sensible solution to your immediate problem is (2 *) . length, as 9000 pointed out, it is worth dwelling a bit on why length [(1,2),(2,3),(3,4)] doesn't do what you expect. A Haskell list contains an arbitrary number of elements of the same type. A Haskell pair, however, has exactly two elements of possibly different types, which is something quite different and which is not implicitly converted into a list (see this question for further discussion of that point). However, nothing stops us from writing a conversion function ourselves:
pairToList :: (a, a) -> [a]
pairToList (x, y) = [x, y]
Note that the argument of pairToList is of type (a, a); that is, the function only accepts pairs with both elements having the same type.
Given pairToList, we can convert the pairs in your list...
GHCi> map pairToList [(1,2),(2,3),(3,4)]
[[1,2],[2,3],[3,4]]
... and then proceed as you planned originally:
GHCi> (length . concat . map pairToList) [(1,2),(2,3),(3,4)]
6
The concatMap function combines map and concat into a single pass...
GHCi> :t concatMap
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
... and so your function becomes simply:
GHCi> (length . concatMap pairToList) [(1,2),(2,3),(3,4)]
6
length [(1,2),(2,3),(3,4)] gives you 3 because there are precisely three elements in the list where the elements are tuples, each consisting of two integers. use this function to get all the "elements"
tupleLength :: [(Int, Int)] -> Int
tupleLength = (*2) . length

Replacing element in a list of lists in Haskell

I have a list of lists like so:
[["BBBBBBBB",
"BWFFFPFGB",
"BWFFFPFGB",
"BWFFMPFGB",
"BWFFFPF_B",
"BWFFFPF6B",
"BBBBBBB"]]
I've done a little research and have found out how to access individual elements using the !! operator. But when it comes to searching for a certain element 'M' I'm not sure how to go about that. My friend said I need to use something like (x:xs):xss on a list, but when I try this in the WinGHCi haskell program I get this.
Prelude> let list = [["BBBBBBBB",
"BWFFFPFGB",
"BWFFFPFGB",
"BWFFMPFGB",
"BWFFFPF_B",
"BWFFFPF6B",
"BBBBBBB"]]
Prelude> head(x:xs):xss
<interactive>:192:2: Not in scope: `x'
<interactive>:192:4: Not in scope: `xs'
<interactive>:192:8: Not in scope: `xss'
I understand that I declare the name as list and not x:xs but even when I declare it as x:xs I still get the errors. I'm probably still a little new to haskell to really understand what to do so I may be going about this way wrong.
I've looked here Replace individual list elements in Haskell? because eventually I want to replace the M with something different but I'm not completely sure how I would implement that.
Any help/guidance is appreciated, thanks!
First let's see how to replace a W with M
charWM :: Char -> Char
charWM 'W' = 'M' -- If you see W, put M.
charWM x = x -- If you see anything else, put it back as is.
You can rewrite that function how you like by adding other letter transformations.
Now let's make that work over a list. There's a great function map :: (a ->b) -> [a] -> [b] that lets you apply a function on every element on a list.
stringWM :: String -> String
stringWM xs = map charWM xs -- do charWM to everything in xs.
For example stringWM "QWERTY WILL WIN" = "QMERTY MILL MIN"
Next we can do that to a list of lists:
lolWM :: [String] -> [String]
lolWM xss = map stringWM xss
(String is a type synonym for [Char].)
Let's test that out in ghci:
*Main> list'
["BBBBBBBB","BWFFFPFGB","BWFFFPFGB","BWFFMPFGB","BWFFFPF_B","BWFFFPF6B","BBBBBBB"]
*Main> lolWM list'
["BBBBBBBB","BMFFFPFGB","BMFFFPFGB","BMFFMPFGB","BMFFFPF_B","BMFFFPF6B","BBBBBBB"]
All good.
Your example wasn't exactly list', it was [list'] which has 1 element, so to work on that we'd need to map lolWM. Often we wouldn't bother writing stringWM or lolWM and go directly to lists of lists of lists, if that's what we needed:
lololWM = (map.map.map) charWM
map.map.map means map the map of the map. You can allow that to blow your mind a little, or you can just say list of list of list of Char, so map map map - one map per list level.
In the future, maybe you'll want to replace W with Strings instead of characters.
rewriteChar :: Char -> String
rewriteChar 'W' = "--^--"
rewriteChar x = [x] -- put x in a list to make it a string
This time, map isn't enough: map rewriteChar "QWERTY WILL WIN" gives
["Q","--^--","E","R","T","Y"," ","--^--","I","L","L"," ","--^--","I","N"]
We could use concat on that to flatten it into a single list, but it's more fun to do
rewriteString = concatMap rewriteChar
So now rewriteString "QWERTY WILL WIN" give us "Q--^--ERTY --^--ILL --^--IN".
For more mindblowing things to try, there's "QWERTY WILL WIN" >>= rewriteChar and "Hello Mum" >>= \x -> [x,x,x]
First of all, virtually all "variables" in Haskell are immutable, so there's no "changing a list", there are modified copies.
Second, you need to find an element by some criteria. To do that, you need to traverse a list. - This can be done using recursion. Filtering can be done using a function passed as an argument of your traversing function (this function must take an element and return a boolean value).
Try to put the above together and make your own function. Start with a type signature, it shows what you want to do: to take a list of Char (it's better to generalize to a generic type) and a function which possibly changes an element and return a modified list:
replaceFunc :: (Char -> Char) -> String -> String
Also, read http://www.haskell.org/haskellwiki/How_to_work_on_lists , there's a hint there how to apply some function to specific elements only.