This algebraic data type can be represented as its catamorphism, a transformation known as Church coding . This means that lists are isomorphic to them foldr
:
type List a = forall b. (a -> b -> b) -> b -> b
fromList :: [a] -> List a
fromList xs = \f z -> foldr f z xs
toList :: List a -> [a]
toList l = l (:) []
But foldr
also characterizes Foldable
. You can define foldMap
in terms foldr
and vice versa.
foldMap f = foldr (mappend . f) mempty
foldr f z t = appEndo (foldMap (Endo . f) t) z
(No wonder what foldMap :: Monoid m => (a -> m) -> [a] -> m
characterizes lists, because lists are a free monoid.) In other words, Foldable
basically gives you toList
as a class. Instances Foldable
have a "path" that you can go through to give you a list; Foldable
have at least such a structure as lists.
Regarding your concerns:
, Foldable
head
/tail
/isEmpty
, .
null :: Foldable t => t a -> Bool
isEmpty
, ( ) head
Monoid
:
head :: Foldable t :: t a -> Maybe a
head = getFirst . foldMap (First . Just)
tail
, , . , tail
. , , tail :: Foldable t => t a -> Maybe [a]
( toList
ing, ), , T
, tail :: T a -> Maybe (T a)
, (, Seq
). , , , , tail
, .
, . megaparsec
, , Stream
() , .