Reputation: 367
my function append takes a list of lists [[a], [b,c], [d,e]] and returns a single list [a,b,c,d,e]. I wrote this in a file so i didn't have to use "let" but i still get parse error on input '='. can anyone help? thanks
append :: [[a]] -> [a]
append [[a]] = [ a | len = length a, n = 1, head a ++ (a !! n) , n < len]
Upvotes: 0
Views: 92
Reputation: 54068
You need let
for len
and n
:
append [[a]] = [a | let len = length a, let n = 1, head a ++ (a !! n), n < len]
But this won't solve all of your problems, once the let
s are added it doesn't typecheck, and [[a]]
is probably not the pattern you want to use here. The pattern [[a]]
will only match a list like [[1]]
, it won't match []
, or [[1, 2]]
, or [[1], [2]]
.
You also have another problem that head a ++ (a !! n)
should be an expression that returns a Bool
, but in this case it's returning a list. Any "naked" expressions on the right side of the |
in a list comprehension must evaluate to a Bool
value.
If you're wanting to flatten a list of lists, I would suggest looking at the built-in concat
function, which is actually defined using foldr
. Folds can be tricky to learn, though, so I'll show an alternate definition using explicit recursion:
myconcat :: [[a]] -> [a]
myconcat [] = []
myconcat (x:xs) = x ++ myconcat xs
This is equivalent to the foldr
definition, but hopefully it can be more instructive to how to solve this sort of problem.
Upvotes: 4
Reputation: 370367
You still need to use let
to define local variables inside a list comprehension regardless of whether or not the code is in a file. The code being in a file only makes a difference for top-level definitions. Local definitions stay the same.
So the syntactically correct version of your code would be:
append :: [[a]] -> [a]
append [[a]] = [ a | let len = length a, let n = 1, head a ++ (a !! n) , n < len]
-- ^^^ ^^^
Upvotes: 0