I want to use 'head' function inside map.
The problem is the 'head' function only accepts non-empty list.
I have list of list:
let ll =[["dog", "cat"], ["pig", "cow"], []]
I need to iterate the list of list twice
let listOne = filter(\x -> if length x > 0) ll
map(\x -> head x) listOne
I'm wondering whether I can iterate the list of list once or put a "if condition" inside the map without the 'filter'
Any suggestion would be appreciated.
Yes, in fact you can write it as a list comprehension statement, and use pattern matching instead:
result = [ h | (h:_) <- ll ]
or as a function:
heads :: [[a]] -> [a]
heads ll = [ h | (h:_) <- ll ]
So here we use the pattern (h:_) which matches all non-empty lists, and we directly obtain the head h of such list and add it to the list. If you use a pattern in list comprehension (on the left side of the left arrow <-, it will skip the elements that do not match the pattern).
This is also more safe than using length, since length will get stuck into an infinite loop if you are working with infinite lists. Furthermore by using patterns over the non-total head function, we have more syntactical guarantees that this function will work (yes, once the non-empty elements are filtered, we are of course certain that head will not result in errors, but we only know this because we have information about the head function).
Note that your attempt will result in a syntax error, since you use an if, without a then and else part.
Alternatively, we can, like #DanielWagner says, write the heads function differently, for instance using:
heads :: [[a]] -> [a]
heads ll = concatMap (take 1) ll
or by using the bind of the list monad:
heads :: [[a]] -> [a]
heads = (take 1 =<<)
or we can transpose the 2d list. In that case the first row contains all the heads of the lists. Since it is however not guaranteed that there is such a row, we can append an empty list at the end, like:
heads :: [[a]] -> [a]
heads = head . (++ [[]]) . transpose
Related
I'm beginner in haskell and I tried to add a number in a 2D list with specific index in haskell but I don't know how to do
example i have this:
[[],[],[]]
and I would like to put a number (3) in the index 1 like this
[[],[3],[]]
I tried this
[array !! 1] ++ [[3]]
but it doesn't work
As you may have noticed in your foray so far, Haskell isn't like many other languages in that it is generally immutable, so trying to change a value, especially in a deeply nested structure like that, isn't the easiest thing. [array !! 1] would give you a nested list [[]] but this is not mutable, so any manipulations you do this structure won't be reflected in the original array, it'll be a separate copy.
(There are specialized environments where you can do local mutability, as with e.g. Vectors in the ST monad, but these are an exception.)
For what you're trying to do, you'll have to deconstruct the list to get it to a point where you can easily make the modification, then reconstruct the final structure from the (modified) parts.
The splitAt function looks like it will help you with this: it takes a list and separates it into two parts at the index you give it.
let array = [[],[],[]]
splitAt 1 array
will give you
([[]], [[],[]])
This helps you by getting you closer to the list you want, the middle nested list.
Let's do a destructuring bind to be able to reconstruct your final list later:
let array = [[],[],[]]
(beginning, end) = splitAt 1 array
Next, you'll need to get at the sub-list you want, which is the first item in the end list:
desired = head end
Now you can make your modification -- note, this will produce a new list, it won't modify the one that's there:
desired' = 3:desired
Now we need to put this back into the end list. Unfortunately, the end list is still the original value of [[],[]], so we'll have to replace the head of this with our desired' to make it right:
end' = desired' : (tail end)
This drops the empty sub-list at the beginning and affixes the modified list in its place.
Now all that's left is to recombine the modified end' with the original beginning:
in beginning ++ end'
making the whole snippet:
let array = [[],[],[]]
(beginning, end) = splitAt 1 array
desired = head end
desired' = 3:desired
end' = desired' : (tail end)
in beginning ++ end'
or, if you're entering all these as commands in the REPL:
let array = [[],[],[]]
let (beginning, end) = splitAt 1 array
let desired = head end
let desired' = 3:desired
let end' = desired' : (tail end)
beginning ++ end'
As paul mentions, things in Haskell are immutable. What you want to do must be done not be modifying the list in place, but by destructuring the list, transforming one of its parts, and restructuring the list with this changed part. One way of destructuring (via splitAt) is put forth there; I'd like to offer another.
Lists in Haskell are defined as follows:
data [] a = [] | a : [a]
This reads "A list of a is either empty or an a followed by a list of a". (:) is pronounced "cons" for "constructor", and with it, you can create nonempty lists.
1 : [] -> [1]
1 : [2,3] -> [1,2,3]
1 : 2 : 3 : [] -> [1,2,3]
This goes both ways, thanks to pattern matching. If you have a list [1,2,3], matching it to x : xs will bind its head 1 to the name x and its tail [2,3] to xs. As you can see, we've destructured the list into the two pieces that were initially used to create it. We can then operate on those pieces before putting the list back together:
λ> let x : xs = [1,2,3]
λ> let y = x - 5
λ> y : xs
[-4,2,3]
So in your case, we can match the initial list to x : y : z : [], compute w = y ++ [3], and construct our new list:
λ> let x : y : z : [] = [[],[],[]]
λ> let w = y ++ [3]
λ> [x,w,z]
[[],[3],[]]
But that's not very extensible, and it doesn't solve the problem you pose ("with specific index"). What if later on we want to change the thousandth item of a list? I'm not too keen on matching that many pieces. Fortunately, we know a little something about lists—index n in list xs is index n+1 in list x:xs. So we can recurse, moving one step along the list and decrementing our index each step of the way:
foo :: Int -> [[Int]] -> [[Int]]
foo 0 (x:xs) = TODO -- Index 0 is x. We have arrived; here, we concatenate with [3] before restructuring the list.
foo n (x:xs) = x : foo (n-1) xs
foo n [] = TODO -- Up to you how you would like to handle invalid indices. Consider the function error.
Implement the first of those three yourself, assuming you're operating on index zero. Make sure you understand the recursive call in the second. Then read on.
Now, this works. It's not all that useful, though—it performs a predetermined computation on a specified item in a list of one particular type. It's time to generalize. What we want is a function of the following type signature:
bar :: (a -> a) -> Int -> [a] -> [a]
where bar f n xs applies the transformation f to the value at index n in the list xs. With this, we can implement the function from before:
foo n xs = bar (++[3]) n xs
foo = bar (++[3]) -- Alternatively, with partial application
And believe it or not, changing the foo you already wrote into the much more useful bar is a very simple task. Give it a try!
for example:
My list of lists in Haskell is:
[[1,2,3], [7,6,8], [0,3,4]]
I need all first element of ervery list in list.
How can I get the output [1,7,4] without "map"?
I need a solution with pattern-matching, not this:
list x = map head x
Look at definitions of map and head functions. And then just copy implementations, combining both functions in one. To make it easier, you can just copy map, replacing function, passed to map with head and then use your own head. You can use case <expr> of ... expression to not implement your own head as a separate function. After doing all this stuff, you can probably refactor your function to make it more elegant.
firsts [] = []
firsts [(x:xs)] = [x]
firsts ((x:xs):xss) = x: firsts xss
> firsts [[1,2,3], [7,6,8], [0,3,4]]
[1,7,0]
I'm new to Haskell but this is what I managed to create here.
I used list comprehension and pattern matching.
--Type definition. Not mandatory but recommended.
firstItemOfEveryList :: [[a]] -> [a]
--First pattern. If the list is empty return a empty list.
firstItemOfEveryList [] = []
--Catch all pattern. Receive a list of lists (xxs). For every inner list (xs <- xxs) call the head method (head xs), but only when the inner list is not null or empty (not(null xs).
firstItemOfEveryList xxs = [head xs | xs <- xxs, not(null xs)]
The empty list pattern is a little bit unnecessary, as it just gives the same result that the last catch. Hope it helps.
Another answer using nested pattern matching:
firsts :: [[a]] -> [a]
firsts [] = []
firsts ([]:xss) = error "sublist is empty"
firsts ((x:xs):xss) = x:firsts xss
Ok so have been faced with a problem where basically I have a been told to make a multiset, or a list of tuples. (Char,Int) and then I have to write a function that takes a item and inserts it into this list, but if there is already a matching tuple in the list it increases the Int.
i.e. i had a list [(p,2),(w,3)] and i get another w it should give [(p,2),(w,4)]
How would you go about it, i've tried
listAdd :: Char->Int->ListOfT -> ListOfT
listAdd c i l
|length l == 0 =(c,i):l
|fst l == c = (c,i+1):l
but this gives loads of errors, i need to remove the list element at that point and replace it with with (c,i+1), so how do i remove from the list and how to i get i+1? also how do you make a loop which will go through all the elements in a list?
And i can't use any of the import Data stuff
I know this is asking a ton but any help would be great thanks.
Neo
Okay can this code be fiddled with so it can be used tto make tuples of any items not just chars. so i could load it up and make a list of tuples with stirngs instead, close it then load it up again and make a list of tuples of ints?
ok I think your idea is not bad you just have to get the details straight.
The loop you asked about is usually either done with recursion (as a list is a recursive structure that's a great idea) or with some higher order functions like map, filter, foldr, ... that will hide the recursion from you (you could say they abstract away the repeating stuff) - anway in this case I think the easiest way is just to go with what you started and use the direct recursion.
Here is a simple version (you maybe want to extent) that does the basic stuff:
listAdd :: Char -> [(Char,Int)] -> [(Char,Int)]
listAdd c [] = [(c,1)]
listAdd c ((c',i):xs)
| c' == c = (c,i+1):xs
| otherwise = (c',i) : listAdd c xs
as you can see the first case is very similar to what you had: if the dictionary (the second argument) is the empty list than you just add a new tuple with the char to insert and the number 1
if not then you check if the first element in the dictionary has the same character (c' here), if yes then you increase the count and if not you let this element stand as it is and recursively search through the rest of the dictionary.
Also note that you can use pattern matching here to not only deconstruct the dictionary into head::tail form but also deconstruct the head into (..,..) tuple parts as well.
If you want you can use a # in there to and get the second case a bit more concise:
listAdd :: Char -> [(Char,Int)] -> [(Char,Int)]
listAdd c [] = [(c,1)]
listAdd c (x#(c',i):xs)
| c' == c = (c,i+1):xs
| otherwise = x : listAdd c xs
PS: in case you wondered why I did not use your Int argument? Because I don't know what you want to do with it if there is already a value - here is a version where I just add it to it (seems resonable):
listAdd :: Char -> Int -> [(Char,Int)] -> [(Char,Int)]
listAdd c i [] = [(c,i)]
listAdd c i (x#(c',i'):xs)
| c' == c = (c,i+i'):xs
| otherwise = x : listAdd c i xs
List manipulations with just recursive functions can be indeed hard for beginners to grok, but in this case they should fit the problem nicely.
Let's start with a bit better signature and a helper.
type MyList = [(Char, Int)]
listAdd :: Char -> MyList -> MyList
listAdd p l = listAdd' p [] l
Notice that I've changed the signature to accept just Char; we don't need to supply the initial count, since if there are no such elements currently on the list, we'll just set it to 1 when adding a new element.
Okay, that's the basic skeleton. The helper is there just to make it easier to store the "already processed" part of the list. Let's look at it:
listAdd' :: Char -> MyList -> MyList -> MyList
First, we add the recursion end condition:
listAdd' p left [] = left ++ [(p, 1)]
This means that if we haven't found the element to replace earlier, we can just add it at the end.
listAdd' p left (x:right) = if p == fst x
then left ++ [(fst x, snd x + 1)] ++ right
else listAdd' p (left ++ [x]) right
Okay, so now we split up the "right" part to the first element of it and the rest. Let's look at the if:
if we managed to find the element, we can end the computation by appending the rest of the list to the modified element and what we had previously
if it's still not it, we proceed with recursion.
As an additional remark at the end, you could easily change Char to Eq a => a to allow your function to work on any type that can be directly compared, Char included.
I'm new to F# and I'm trying to write a method split that splits a list into 2 pieces. It takes a tuple with the first element being the number of elements to split and the second element is the list . For example, split (2, [1;2;3;4;5;6]) should return ([1;2], [3;4;5;6]),
This is what I have so far, but for some reason it is returning the second element of the tuple as the original list without the head. I don't understand this because I thought that x::xs automatically makes x the head element and xs the rest of the list, which would mean that each recursive call is taking the tail of the previous list and chopping off the first term.
let rec split = function
|(n, []) -> ([], [])
|(0, xs) -> ([], xs)
|(n, x::xs) -> let temp = x :: fst (split(n-1, xs))
(temp, xs);;
The problem is on this line:
(temp,xs);;
here in your example, xs will always be [2;3;4;5;6] as long as n>0
You need to get the second element of the list with something like
|(n,x::xs) ->
let a,b = split (n-1,xs)
(x::a,b)
I have been working with Haskell for a little over a week now so I am practicing some functions that might be useful for something. I want to compare two lists recursively. When the first list appears in the second list, I simply want to return the index at where the list starts to match. The index would begin at 0. Here is an example of what I want to execute for clarification:
subList [1,2,3] [4,4,1,2,3,5,6]
the result should be 2
I have attempted to code it:
subList :: [a] -> [a] -> a
subList [] = []
subList (x:xs) = x + 1 (subList xs)
subList xs = [ y:zs | (y,ys) <- select xs, zs <- subList ys]
where select [] = []
select (x:xs) = x
I am receiving an "error on input" and I cannot figure out why my syntax is not working. Any suggestions?
Let's first look at the function signature. You want to take in two lists whose contents can be compared for equality and return an index like so
subList :: Eq a => [a] -> [a] -> Int
So now we go through pattern matching on the arguments. First off, when the second list is empty then there is nothing we can do, so we'll return -1 as an error condition
subList _ [] = -1
Then we look at the recursive step
subList as xxs#(x:xs)
| all (uncurry (==)) $ zip as xxs = 0
| otherwise = 1 + subList as xs
You should be familiar with the guard syntax I've used, although you may not be familiar with the # syntax. Essentially it means that xxs is just a sub-in for if we had used (x:xs).
You may not be familiar with all, uncurry, and possibly zip so let me elaborate on those more. zip has the function signature zip :: [a] -> [b] -> [(a,b)], so it takes two lists and pairs up their elements (and if one list is longer than the other, it just chops off the excess). uncurry is weird so lets just look at (uncurry (==)), its signature is (uncurry (==)) :: Eq a => (a, a) -> Bool, it essentially checks if both the first and second element in the pair are equal. Finally, all will walk over the list and see if the first and second of each pair is equal and return true if that is the case.