如何实现“两个单子的乘积”影响?
假设我们有两个 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
有没有办法创建类似于产品 mx 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')
。
Suppose we have two monads, m
and m'
. Now, suppose we have variables,
-- 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
Is there a way to create anything similar to the product m x m'
? I know this is possible with Arrows, but it seems more complicated (impossible?) for monads, especially when trying to write what mx >>= f
should do.
To see this, define
data ProdM a = ProdM (m a) (m' a)
instance Monad ProdM where
return x = ProdM (return x) (return x)
but now, when we define mx >>= f
, it's not clear which value from mx
to pass to f
,
(ProdM mx mx') >>= f
{- result 1 -} = mx >>= f
{- result 2 -} = mx' >>= f
I want (mx >>= f) :: ProdM
to be isomorphic to ((mx >>= f) :: m) x ((mx >>= f) :: m')
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,这个类型是一个 monad。关键是将两个结果传递给
f
,并且只保留结果中的匹配字段。也就是说,我们保留传递mx
的结果中的第一个元素,以及传递mx'
的结果中的第二个元素。该实例如下所示:ProdM
可在 monad-products 名为Product
的包。Yes, this type is a monad. The key is simply to pass both results to
f
, and only keep the matching field from the result. That is, we keep the first element from the result of passingmx
's result, and the second element from the result of passingmx'
's result. The instance looks like this:ProdM
is available in the monad-products package under the nameProduct
.