Foldable
is to Functor
as Traversable
is to Monad
, i.e. Foldable
and Functor
are superclasses of Monad
and Traversable
(modulo all the applicative/monad proposal noise).
Indeed, that's already in the code
instance Foldable f => Traversable f where
...
So, it's not clear what more there is to want. Foldable
is characterized by toList :: Foldable f => f a -> [a]
while Traversable
depends ultimately on not only being able to abstract the content as a list like toList
does, but also to be able to extract the shape
shape :: Functor f => f a -> f ()
shape = fmap (const ())
and then recombine them
combine :: Traversable f => f () -> [a] -> Maybe (f a)
combine f_ = evalStateT (traverse pop f_) where
pop :: StateT [a] Maybe a
pop = do x <- get
case x of
[] = empty
(a:as) = set as >> return a
which depends on traverse
.
For more information on this property see this blog post by Russell O'Connor.