If I have this insert function:
insert x [] = [x]
insert x (h:t)
| x <= h = x:(h:t)
| otherwise = h:(insert x t)
this produces a sorted list:
foldr insert [] [1,19,-2,7,43]
but this:
foldr1 insert [1,19,-2,7,43]
produces 'cannot construct the infinite type: a0 = [a0]'
I'm confused about why the second call cannot work.
I have looked at the definitions for both foldr and foldr1 and have traced both with simple arithmetic functions, but I still cannot come up with a clear explanation for why the second call fails.
Let's look at some type signatures.
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr1 :: (a -> a -> a) -> [a] -> a
In both cases, the first argument is a function of two arguments.
foldr1, these two arguments must have the same type (and the result has this type also)foldr, these two arguments may have different types (and the result has the same type as the second argument)What's the type of your insert?
I like the type-based answers given here, but I also want to give an operational one explaining why we don't want this to typecheck. Let's take the source of foldr1 to start with:
foldr1 :: (a -> a -> a) -> [a] -> a
foldr1 _ [x] = x
foldr1 f (x:xs) = f x (foldr1 f xs)
Now, let's try running your program.
foldr1 insert [1,19,-2,7,43]
= { list syntax }
foldr1 insert (1:[19,-2,7,43])
= { definition of foldr1 }
insert 1 (foldr1 insert [19,-2,7,43])
= { three copies of the above two steps }
insert 1 (insert 19 (insert (-2) (insert 7 (foldr1 insert [43]))))
= { definition of foldr1 }
insert 1 (insert 19 (insert (-2) (insert 7 43)))
...whoops! That insert 7 43 is never going to work. =)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With