I newbie in Haskell, when i run scanl function in haskell with these parameters it works fine:
ghci> scanl (flip(:))[] [3,2,1]
[[],[3],[2,3],[1,2,3]]
but if i do the same but using the scanr function i get this error:
ghci> scanr (flip(:))[] [3,2,1]
<interactive>:129:8: error:
• Couldn't match type ‘a’ with ‘[a]’
Expected: [[a]] -> [a] -> [a]
Actual: [[a]] -> [a] -> [[a]]
• In the first argument of ‘scanr’, namely ‘(flip (:))’
In the expression: scanr (flip (:)) [] [3, 2, 1]
In an equation for ‘it’: it = scanr (flip (:)) [] [3, 2, 1]
• Relevant bindings include
it :: [[a]] (bound at <interactive>:129:1)
What am i doing wrong?
What would I have to change to be able to use the scanr function with the same parameters?
Thank you!!!
>Solution :
The first parameter in the scanl and scanr functions are swapped, indeed:
scanl :: (b -> a -> b) -> b -> [a] -> [b]
scanr :: (a -> b -> b) -> b -> [a] -> [b]
This makes sense since for scanl f z [x1, x2, …, xn] it will produce:
[z, f z x1, f (f z x1) x2), …, f (f (… (f z x1) …) xn-1) xn)]
whereas for scanr, this gives us:
[f x1 (f x2 (…(f xn z)…)), …, f xn-1 (f xn z), f xn z, z]
The order thus makes it more clear how it will "fold".
You thus run this with:
scanr (:) [] [1,2,3,4]
which produces:
[[1,2,3,4],[2,3,4],[3,4],[4],[]]
scanr takes thus as first parameter the element of the list, and as second the thus far generated accumulated value.