Haskell 如何实现;“两个单体的乘积”;效果如何?
假设我们有两个单子,Haskell 如何实现;“两个单体的乘积”;效果如何?,haskell,monads,Haskell,Monads,假设我们有两个单子,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
和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
是否有一种方法可以创建类似于产品的东西mxm'
?我知道这对于箭头是可能的,但对于单子来说似乎更复杂(不可能),特别是当试图编写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')
是的,此类型是单子。关键是将两个结果都传递给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
在软件包中以Product
的名称提供。ehird的解决方案还意味着操作f运行两次。如果单子m和m'有明显的副作用,这可能是意外的。