Reputation: 453
foldr (\x ante->[x]:[ante]) [4] [1,2,3]
So if I get foldr right, the first time the function (\x ante->[x]:[ante])
will do something, I will call this function f, it will be in:
f 3 [4] = [3]:[[4]] = [[3],[4]]
Why doesn't the function do this? It shows this error instead:
* Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [a]
Actual type: [[a]]
* In the expression: [x] : [ante]
In the first argument of `foldr', namely
`(\ x ante -> [x] : [ante])'
In the expression: foldr (\ x ante -> [x] : [ante]) [4] [1, 2, 3]
* Relevant bindings include
ante :: [a] (bound at testefoldr.hs:51:21)
x :: a (bound at testefoldr.hs:51:19)
folder4 :: [a] (bound at testefoldr.hs:51:1)
|51 | folder4 = foldr (\x ante->[x]:[ante]) [4] [1,2,3]
I created a .hs
then I put
folder4 = foldr (\x ante->[x]:[ante]) [4] [1,2,3]
for faster testing. That's why there is folder4 in the error.
Upvotes: 2
Views: 71
Reputation: 477190
The foldr
function has type:
foldr :: (a -> b -> b) -> b -> [a] -> b
So that means that it takes as input an element (type a
) of the list to fold, together with the accumulator (type b
), and returns an accumulator (again type b
). In case Haskell was not statically typed, it would each time wrap the accumulator in a new list. So it would result in:
[4]
-> [[3],[4]]
-> [[2],[[3],[4]]]
-> [[1],[[2],[[3],[4]]]]
which makes no sense.
There are two problems here:
ante
has type b
, then [x] : [ante]
has type [b]
; and[4]
is not the result of the foldr.So you can fix this by writing:
foldr (\x ante->[x]:ante) [[4]] [1,2,3]
Upvotes: 4
Reputation: 116174
Let's pretend this type checks, and run it anyway
foldr (\x ante->[x]:[ante]) [4] [1,2,3]
Let's write f
for \x ante -> [x]:[ante]
.
foldr f [4] [1,2,3]
=
f 1 (f 2 (f 3 [4]))
=
f 1 (f 2 ([3]:[[4]]))
=
f 1 (f 2 [[3],[4]])
So far, so good.
=
f 1 ([2] : [[[3],[4]]])
=
f 1 [[2] , [[3],[4]] ]
Now we're in trouble. Is that a [[Int]]
or a [[[Int]]]
?
Things get even worse if we continue.
The problem is that f
must return a value of the same type as that of its second argument. Otherwise, we can't compose f
in the way foldr
does. Your f
does not do that, instead adding a []
to the type at every call.
Upvotes: 3