While studying Applicative deeper, I came to Traversable. Although I already knew Foldable from LYHGG, I haven't seen the former yet, so I started reading the Haskell wiki about Traversable.
While reading it, I understood why Foldable.fold is parallel to Traversable.sequenceA and Foldable.foldMap is parallel to Traversable.traverse.
I've seen also that every Traversable is also a Foldable and a Functor, and sequenceA and traversal have a default implementation in terms of each other:
traverse f = sequenceA . fmap f
sequenceA = traverse id
So, as I have seen in LYHGG that foldMap is a minimal complete definition for Foldable, I thought that, it is parallel to traverse, so fold (which is parallel to sequenceA) would be a minimal complete definition too (which it isn't)... Foldable is not a Functor like Traversable is, so we cannot apply this:
foldMap f = fold . fmap f
fold = foldMap id -- this is ok
Why isn't every Foldable a Functor, and what would be an instance of Foldable that actually isn't a Functor?
Traversable in Haskell unifies the concept of mapping over a container (getting a similary-shaped container in return) with the concept of "internal iterator" that performs an effect for each element.
Haskell, in turn, has two fundamental functions representing reducing, or, as we call it, folding – foldl and foldr – that differ in the order of the folding. foldl reduces elements of a container from left to right (as reduce in other languages usually does), while foldr reduces from right to left.
As dfeuer says, Set is a good example of a Foldable that isn't a Functor.
Consider the type of Set.map:
map :: Ord b => (a -> b) -> Set a -> Set b
Notice that this is almost fmap, but it requires an additional Ord b constraint. Since you have this constraint, it can't be made an instance of Functor.
Note that Set is not a functor on Haskell, even with this restriction. Given cleverly set-up Eq instances we can break the law that fmap f . fmap g === fmap (f . g). See this Stack Overflow question for further discussion.
As noted there, Set is an (endo) functor on the "subcategory of Hask" with ordered types as sets and with order-preserving maps as morphisms.
So even if it isn't apparent, the fact that we can't make Set a functor actually hints at a genuine mathematical issue and not just a limitation of our typeclass machinery.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With