Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unclear about foldl type definition

Tags:

haskell

foldl :: (a -> b -> a) -> a -> [b] -> a
foldl step zero (x:xs) = foldl step (step zero x) xs
foldl _    zero []     = zero

I don't quite understand why does (a -> b -> a) return a, also (a -> b -> a) -> a -> [b] -> a return a. I would think it should be like: (a -> b -> c) -> a -> [b] -> c. Can someone explain that to me based on the example below. Thanks!

foldl (+) 0 (1:2:3:[])
foldl (+) (0 + 1) (2:3:[])
foldl (+) ((0 + 1) + 2) (3:[])
foldl (+) (((0 + 1) + 2) + 3) ([])
foldl (+) (((0 + 1) + 2) + 3)
like image 445
user342673 Avatar asked Feb 08 '13 08:02

user342673


1 Answers

a represents the type of the accumulator value, and b represents the type of each element in the input. (a -> b -> a) is a function that takes an accumulator value, some item in the list, and returns a new accumulator value that can be passed onto the next step.

The type of the initial value must be a so that the first invocation of the function can receive an accumulator value. The accumulator function must take an a and return an a so that an accumulator value can be passed to each step of the fold. The final value of the fold must necessarily be an a, because that is the type of the accumulator that will be returned by the final call the fold function.

(a -> b -> c) -> a -> [b] -> c cannot represent a fold, because the folding function does not take a c. The input and output of the folding function must be the same type so the accumulator can be passed to the next fold step.

Let's see an example of what would happen if the fold function returned a c.

f :: Integer -> Integer -> Bool   -- this is a valid (a -> b -> c)
f acc n = (acc + n) > 0

Pretend we're using a dynamic language and we try to fold with f. What happens at runtime?

foldl f 0 [1]     ~ (0 + 1) > 0            == True :: Bool

foldl f 0 [1, 2]  ~ ((0 + 1) > 0) + 2) > 0 == error - no instance of (+) for Bool
                     \_________/   \
                          |         \
                         Bool      + Integer

You can see that you can't make a fold work if you try to accumulate with incompatible types.

like image 161
Chris Barrett Avatar answered Nov 23 '22 14:11

Chris Barrett