What I don't get is how it is possible to use foldl in this way in haskell. I do not understand how the argument ( in this case list) is carried over implicitly:
addAll :: [Int] -> Int
addAll = foldl (+) 0
-- This is how I could write foldl to simplify addAll where xs is clearly defined
addAll :: [Int] -> Int
addAll xs = foldl (+) 0 xs
or
addAll :: [Int] -> Int
addAll = \ xs -> foldl (+) 0 xs
But I don't really understand the first example. So basically I wonder how it is possible for something to be evaluated like that in haskell?
But I don't really understand the first example. So basically I wonder how it is possible for something to be evaluated like that in haskell?
The foldl (+) 0
produces a function. A function of type (Foldable f, Num a) => f a -> a
, so why would you need an extra parameter? The addAll
is a function as well.
In functional programming, functions are "first class citizens". This means that you can pass functions as parameters, and that the result can be a function. In Haskell every function takes exactly one parameter. Indeed:
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
is short for:
foldl :: Foldable t => (b -> a -> b) -> (b -> (t a -> b))
foldl
is thus a function that takes as parameter a function of type (b -> a -> b)
, and produces a function of type b -> t a -> b
. This thus means that foldl (+)
has type:
foldl (+) :: (Foldable f, Num b) => b -> (f b -> b)
again a function that in this case takes a parameter the base case for foldl
, and returns then a function that maps a (Foldable f, Num a) => f a -> f a
. If you write foldl (+) 0
, this is thus short for (fold (+)) 0
.