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 :-) )
Reading Beautiful folding I realized that any
Foldable
can be made aFunctor
by wrapping it intowith a simple smart contructor:
(This is just a variant of the Store comonad data type.)
Now we can define
This way, we can make both
Data.Set.Set
and Sjoerd Visscher'sWeird
a functor. (However, since the structure doesn't memoize its values, repeatedly folding over it could be very inefficient, if the function that we used infmap
is complex.)Update: This also provides an example of a structure that is a functor, foldable but not traversable. To make
Store
traversable, we would need to make(->) r
traversable. So we'd need to implementLet's take
Either b
forf
. Then we'd need to implementClearly, there is no such function (you can verify with Djinn). So we can neither realize
sequenceA
.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
andmap
functions defined forSet
: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 theOrd
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!Here's a fully parametric example:
Weird
is not aFunctor
becausea
occurs in a negative position.