首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在monad实例声明中使用monad超类?

在monad实例声明中使用monad超类?
EN

Stack Overflow用户
提问于 2017-03-16 09:30:26
回答 1查看 99关注 0票数 2

我正在用以下数据类型实现一个非常简单的穷人并发结构:

代码语言:javascript
复制
data C m a = Atomic (m (C m a)) | Done a

我正在为此创建一个monad实例:

代码语言:javascript
复制
instance Monad m => Monad (C m) where
  (>>=) (Atomic m) f      = Atomic $ (liftM (>>= f) m)
  (>>=) (Done v) f        = f v
  return                  = Done

Q1。我说得对吗?Atomic $ (liftM (>>= f) m)正在创建一个新的Atomic monad,其中包含应用于m内部的值的f (* -> *)的结果。

Q2。我说得对吗,在这里使用超类Monad m来启用liftM?如果是这样的话,既然这是Monad类的一个实例,为什么不能直接访问liftM

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-16 10:24:57

Q1。它正在创建Atomic value。Monad是类型级别的映射。因为f>>= of C m a的第二个参数,所以我们知道它的类型。

代码语言:javascript
复制
f :: Monad m => a -> C m b

因此

代码语言:javascript
复制
(>>= f) :: Monad m => C m a -> C m b

是否扩展f以打开其参数,以及

代码语言:javascript
复制
liftM (>>= f) :: (Monad m1, Monad m) => m1 (C m a) -> m1 (C m b)

只需将转换提升到m1,在您的设置中,该转换将与m统一。当您从m提取值Atomic并将其传递给liftM时,您可以使用monad m的绑定(通过liftM)提取要传递给f的内部C m aliftM定义的第二部分将结果重新包装为一个m (C m b),您将其包装在Atomic中。

Q2。是。但它是底层单一市场( monad m )的一个mliftM for C m a是根据实例( >>=return)定义的。通过使用C m aliftM (如果您设法从liftM的角度定义>>= ),您将得到一个循环定义。您需要约束Monad m来创建m (C m a)穿越>>=f的管道。事实上,正如本杰明·霍奇森指出的那样,Monad m是一个不必要的强约束,Functor m就足够了。C实际上是C 39以及相关的C40给出了最深入的见解。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42830035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档