【发布时间】:2017-07-06 05:01:31
【问题描述】:
如果我有两个 monad m 和 n,并且 n 是可遍历的,我是否一定有一个复合 m-over-n monad?
更正式地说,这是我的想法:
import Control.Monad
import Data.Functor.Compose
prebind :: (Monad m, Monad n) =>
m (n a) -> (a -> m (n b)) -> m (n (m (n b)))
mnx `prebind` f = do nx <- mnx
return $ do x <- nx
return $ f x
instance (Monad m, Monad n, Traversable n) => Monad (Compose m n) where
return = Compose . return . return
Compose mnmnx >>= f = Compose $ do nmnx <- mnmnx `prebind` (getCompose . f)
nnx <- sequence nmnx
return $ join nnx
当然,这种类型检查,我相信适用于我检查过的一些情况(Reader over List,State over List)——例如,组合的“monad”满足 monad 法则——但我不确定这是否是通用将任何 monad 分层到可遍历的方法。
【问题讨论】:
-
剧透:是的。
-
有点可悲,如果回想起来很明显,以这种方式在 List 上分层 State 不会给你 非确定性状态,这与你分层 StateT 时发生的情况相反超过列表。
-
如果
Traversable n是完成这项工作的完美约束,那么如果Data.Functor.Compose有实例就好了。也许你应该建议它?我绝对可以想到我可能会使用它的上下文。 -
是的,这就是为什么我开始说“如果 Traversable n 是完美的约束……”也许这有点晦涩。我们当然不想要多个实例,只需要最一般(正确)的实例。