1

I think these two fold functions are the same, but only the second one works. The first one produce No instance for (Num [Char]) arising from the literal ‘12’ error. Why does the first one produce this error?

  1. foldl1 (\x y -> (show x) ++ (show y)) [12,23,45,66]
  2. foldl (\x y -> x ++ (show y)) "" [12,23,45,66]

Thank you

chi
  • 111,837
  • 3
  • 133
  • 218
MaxSha
  • 129
  • 1
  • 7
  • If you want to see something fun, try your first example but with a list of strings instead of a list of numbers – luqui Mar 05 '19 at 02:58

2 Answers2

4

Look closely at the type:

foldl1 :: Foldable t => (a -> a -> a) -> t a -> a

The values need to be converted to [Char] before the function is called, because the function expects its arguments' type and the return type to be the same. (And only the first use of the function gets two arguments of the same type.)

To use foldl1, map show over the list first.

foldl1 (++) (map show [12, 23, 45, 66])
chepner
  • 497,756
  • 71
  • 530
  • 681
3

If you look at the type signature for foldl1 :: Foldable t => (a -> a -> a) -> t a -> a, you'll see that the lambda has to return the same type as the one in the list. This is because that returned value is then used to compute the next step.

This does not occur in foldl because the lambda can return any type as that value is only used as an accumulator. I don't have time to write a more clear answer but just google foldl1 to understand the difference

Lorenzo
  • 2,160
  • 12
  • 29