假设我们有两个monad,m
和m'
。现在,假设我们有变量,
-- in real problems, the restriction is some subclass MyMonad, so don't worry
-- if it's the case here that mx and f must essentially be pure.
mx :: Monad m'' => m'' a
f :: Monad m'' => a -> m'' b
有没有办法创建类似于产品m x m'
的任何内容?我知道这对Arrows来说是可能的,但对monad来说似乎更复杂(不可能?),尤其是在尝试编写mx >>= f
应该做的事情时。
要看到这一点,请定义
data ProdM a = ProdM (m a) (m' a)
instance Monad ProdM where
return x = ProdM (return x) (return x)
但现在,当我们定义mx >>= f
时,不清楚mx
中哪个值传递给f
,
(ProdM mx mx') >>= f
{- result 1 -} = mx >>= f
{- result 2 -} = mx' >>= f
我希望(mx >>= f) :: ProdM
与((mx >>= f) :: m) x ((mx >>= f) :: m')
同构。
答案 0 :(得分:18)
是的,这种类型是monad。关键是将两个结果传递给f
,并且只保留结果中的匹配字段。也就是说,我们保留传递mx
结果的结果中的第一个元素,以及传递mx'
结果的结果中的第二个元素。实例看起来像这样:
instance (Monad m, Monad m') => Monad (ProdM m m') where
return a = ProdM (return a) (return a)
ProdM mx mx' >>= f = ProdM (mx >>= fstProd . f) (mx' >>= sndProd . f)
where fstProd (ProdM my _) = my
sndProd (ProdM _ my') = my'
名称为ProdM
的{{3}}包中提供了 Product
。