简体   繁体   中英

In Data.Data, why does gmapM take a Monad rather than an applicative?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM