A Foldable
instance is likely to be some sort of container, and so is likely to be a Functor
as well. Indeed, this says
A
Foldable
type is also a container (although the class does not technically requireFunctor
, interestingFoldable
s are allFunctor
s).
So is there an example of a Foldable
which is not naturally a Functor
or a Traversable
? (which perhaps the Haskell wiki page missed :-) )
Here's a fully parametric example:
data Weird a = Weird a (a -> a) instance Foldable Weird where foldMap f (Weird a b) = f $ b a
Weird
is not a Functor
because a
occurs in a negative position.
Here's an easy example: Data.Set.Set
. See for yourself.
The reason for this should be apparent if you examine the types of the specialized fold
and map
functions defined for Set
:
foldr :: (a -> b -> b) -> b -> Set a -> b map :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b
Because the data structure relies on a binary search tree internally, an Ord
constraint is needed for elements. Functor
instances must allow any element type, so that's not viable, alas.
Folding, on the other hand, always destroys the tree to produce the summary value, so there's no need to sort the intermediate results of the fold. Even if the fold is actually building a new Set
, the responsibility for satisfying the Ord
constraint lies on the accumulation function passed to the fold, not the fold itself.
The same will probably apply to any container type that's not fully parametric. And given the utility of Data.Set
, this makes the remark you quoted about "interesting" Foldable
s seem a bit suspect, I think!
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