Reputation: 83
I'm stuck on implementing groupBy with a foldr. For some reason when I change a guard condition, the type signature goes ape on me.
I can compile this, albeit its incorrect:
groupBy' :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy' f xs = foldr step [] xs
where step x [] = [x] : []
step x (y:ys)
| True = []:(y:ys)
| otherwise = (x:y):ys
But this does not compile:
groupBy' :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy' f xs = foldr step [] xs
where step x [] = [x] : []
step x (y:ys)
| f x y = []:(y:ys)
| otherwise = (x:y):ys
giving me this error.
Couldn't match type `a' with `[a]'
`a' is an unknown type variable
Expected type: [[a]]
Actual type: [a]
In the second argument of `(:)', namely `ys'
In the expression: (x : y) : ys
In an equation for `step':
step x (y : ys)
| f x y = [] : (y : ys)
| otherwise = (x : y) : ys
I don't get it. Using "f x y" makes it not compile and spit out this error, but when I replace f x y with either True or False, it compiles. I wanna know how I can return []:(y:ys) when "f x y" is true.
Upvotes: 3
Views: 174
Reputation: 5406
Well, in short, the first version y
is of type [a]
, as it is not bound by type signature of f
, and the second you bind y
to be of type a
.
Notice that (y:ys)
of step
is of type [[a]]
, so you really want something like
step x ((y:ys):yss) | f x y = (x:y:ys):yss
step x ys = [x]:ys
Upvotes: 5