gmapM
seems like the obvious candidate for writing a generic traversal based on Data.Data
, for instance, if one wants to implement MonoTraversable
. The only hiccup is that it takes a Monad
rather than an Applicative
. Why is that? Also, is there a similar function to fmapM
with weaker assumptions?
It looks like a historical detail from before implementing the Monad-Applicative proposal.
I can define both the gmapM
default and the instance for lists in terms of Applicative
.
gmapM :: forall m a. (Data a, Applicative m) => (forall d. Data d => d -> m d) -> a -> m a
gmapM f = gfoldl k pure
where
k :: Data d => m (d -> b) -> d -> m b
k c x = c <*> f x
-- instance Data a => Data [a] where ...
gmapMlist :: forall m a. (Data a, Applicative m) => (forall d. Data d => d -> m d) -> [a] -> m [a]
gmapMlist _ [] = pure []
gmapMlist f (x:xs) = (:) <$> f x <*> f xs
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.