如果我有两个单子(monad) m
和 n
, 和 n
是可遍历的,我是否一定有一个复合 m
超过- 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 分层到可遍历的 Monad 上的通用方法。
最佳答案
不,它并不总是一个单子(monad)。您需要额外的兼容性条件来关联两个 monad 的 monad 操作和分配律 sequence :: n (m a) -> m (n a)
,如 Wikipedia 上的示例所述.
Your previous question举一个不满足兼容条件的例子,即
S = m = []
,单位 X -> SX 将 x 发送到 [x];
T = n = (->) Bool
,或等价的 TX = X × X,单位 X -> TX 将 x 发送到 (x,x)。
维基百科页面右下角的图表没有通勤,因为组合 S -> TS -> ST 发送 xs :: [a]
至(xs,xs)
然后是从 xs
中抽取的所有对的笛卡尔积;而右手 map S -> ST 发送 xs
到仅由对 (x,x)
组成的“对角线”对于 x
在 xs
.这也是导致您提出的 monad 不满足其中一个单位定律的问题。
关于haskell - 带有可遍历的任意单子(monad)的组合总是单子(monad)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42284879/