在Data.Data中,为什么gmapM采用Monad而不是应用程序?

时间:2018-05-09 01:04:57

标签: haskell

gmapM似乎是基于Data.Data编写通用遍历的明显候选者,例如,如果想要实现MonoTraversable。唯一的打嗝是需要Monad而不是Applicative。这是为什么?此外,假设较弱的fmapM是否有类似的功能?

1 个答案:

答案 0 :(得分:3)

它看起来像是在实施Monad-Applicative提案之前的历史细节。

我可以根据gmapM定义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