如何实现“两个单子的乘积”影响?

发布于 2024-12-29 01:58:56 字数 935 浏览 1 评论 0原文

假设我们有两个 monad,mm'。现在,假设我们有变量,

-- 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尘曦 2025-01-05 01:58:56

是的,这个类型是一个 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 可在 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 passing mx's result, and the second element from the result of passing mx''s result. The instance looks like this:

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 is available in the monad-products package under the name Product.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文