Is a Type Class for generalising folding up values in data structures of any parameterised Type.
Haskell Declaration
Built-in class declaration from Data.Foldable:
class foldable t where
fold :: Monoid a => t a -> a
foldMap :: Monoid b => (a -> b) -> t a -> b
foldr :: (a -> b -> b) -> b -> t a -> b
foldl :: (a -> b -> a) -> a -> t b -> awhere by convention foldable types are denoted by t.
One must define either foldMap or foldr as all other functions can be derived form either of these.
Other Primitives
In addition to the four folding primitives above the Foldable class also comes with the following useful functions for combining values in a data structure:
null :: t a -> Bool
length :: t a -> Int
elem :: Eq a => a -> t a -> Bool
maximum :: Ord a => t a -> a
minimum :: Ord a => t a -> a
sum :: Num a => t a -> a
product :: Num a => t a -> aIt also includes versions of foldr and foldl for structures containing at least one element (i.e. non-empty), which therefore do not need a starting value:
foldr1 :: (a -> a -> a) -> t a -> a
foldl1 :: (a -> a -> a) -> t a -> aFinally it contains a primitive for flattening a data structure into a List.
toList :: t a -> [a]This can be used to provide default definitions for the other primitives in the class in terms of the corresponding primitives for lists.
Default Relations
The following are default definitions that define relationships between primitives described above
fold = foldMap id
foldMap f = foldr (mappend . f) mempty
toList = foldMap (\x -> [x])Examples
Lists as Foldable
instance Foldable [] where
-- fold :: Monoid a => [a] -> a
fold [] = mempty
fold (x:xs) = x `mappend` fold xs
-- foldMap :: Monoid b => (a -> b) -> [a] -> b
foldMap _ [] = mempty
foldMap f (x:xs) = f x `mappend` foldMap f xs
-- foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ v [] = v
foldr f v (x:xs) = f x (foldr f v xs)
-- foldl :: (a -> b -> a) -> a -> [b] -> a
foldl _ v [] = v
foldl f v (x:xs) = foldl f (f v x) xsBinary Tree as Foldable
instance Foldable Tree where
-- fold :: Monoid a => Tree a -> a
fold (Leaf x) = x
fold (Node l r) = fold l ‘mappend‘ fold r
-- foldMap :: Monoid b => (a -> b) -> Tree a -> b
foldMap f (Leaf x) = f x
foldMap f (Node l r) = foldMap f l ‘mappend‘ foldMap f r
-- foldr :: (a -> b -> b) -> b -> Tree a -> b
foldr f v (Leaf x) = f x v
foldr f v (Node l r) = foldr f (foldr f v r) l
-- foldl :: (a -> b -> a) -> a -> Tree b -> a
foldl f v (Leaf x) = f v x
foldl f v (Node l r) = foldl f (foldl f v l) r