首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读者monad -它如何符合Monad接口?

读者monad -它如何符合Monad接口?
EN

Stack Overflow用户
提问于 2017-02-05 17:55:58
回答 1查看 321关注 0票数 2

我在学习分类理论。我理解reader的概念,它甚至很容易实现:

代码语言:javascript
复制
case class Reader[DEP, A](g: DEP => A) {
  def apply(dep: DEP): A = g(dep)

  def map[B](f: A => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))

  def flatMap[B](f: A => Reader[DEP, B]): Reader[DEP, B] = Reader(dep => f(apply(dep)) apply dep)
}

但是,我在实现它时遇到了一些限制,例如,一些通用的Monad接口。

代码语言:javascript
复制
trait Monad[A] {
  def pure(a: A): Monad[A]

  def map[B](f: A => B): Monad[B]

  def flatMap[B](f: A => Monad[B]): Monad[B]
}

让我们暂时忘记,这里有一个应用程序或函子,让我们把这三个方法放在这里。

现在,有了这个接口,我在实现ReaderMonad时遇到了问题。map方法非常直观,但是单纯和flatMap又如何呢?拥有纯粹的读者意味着什么?要实现flatMap,我需要一个从A到ReaderDEP,B的函数,但是我有A => MonadB,因此我无法访问应用程序。

代码语言:javascript
复制
case class Reader[DEP, A](g: DEP => A) extends Monad[A] {
  def apply(dep: DEP): A = g(dep)

  override def pure(a: A): Reader[DEP, A] = Reader(_ => a) // what does it even mean in case of Reader

  override def map[B](f: (A) => B): Reader[DEP, B] = Reader(dep => f(apply(dep)))

  override def flatMap[B](f: (A) => Monad[B]): Reader[DEP, B] = ??? // to implement it, I need f to be (A) => Reader[DEP, B], not (A) => Monad[B]
}

在scala中可以用这种方式实现它吗?我试着玩自我约束的类型,但它也不起作用。我知道像scalaz或cat这样的库使用类型来实现这些类型,但这只是为了教育目的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-05 19:14:28

正如您在尝试实现flatMap时所发现的那样,像声明Monad特性一样声明Monad特性的问题是,在链接操作时丢失了要定义的特定monad类型。定义Monad特征的通常方法是通过为monad实例定义的类型构造函数对其进行参数化。

代码语言:javascript
复制
trait Monad[M[_]] {
    def pure[A](a: A): M[A]
    def map[A, B](f: A => B, m: M[A]): M[B]
    def flatMap[A, B](f: A => M[B], m : M[A]): M[B]
}

因此,M是一个一元类型的构造函数,如ListOption。您可以将Reader[DEP, A]视为依赖于某些环境类型DEP的计算,该环境类型返回A类型的值。因为这有两个类型参数,所以在定义monad实例时需要修复环境参数类型:

代码语言:javascript
复制
case class Reader[DEP, A](g: DEP => A)

class ReaderMonad[DEP]() extends Monad[({type t[X] = Reader[DEP, X]})#t] {
    def pure[A](a: A) = Reader[DEP, A](_ => a)
    def map[A, B](f: A => B,m: Reader[DEP,A]): Reader[DEP,B] = Reader(env => f(m.g(env)))
    def flatMap[A, B](f: A => Reader[DEP,B],m: Reader[DEP,A]): Reader[DEP,B] = Reader(env => f(m.g(env)).g(env))
}

({type t[X] = Reader[DEP, X]})#t是一个type lambda,用于为Reader[DEP, A]部分应用这两个参数之一。

现在,pure返回一个忽略环境并直接返回给定值的Reader

flatMap构造一个Reader,当运行时将运行内部计算,使用结果构造下一个计算,并在相同的环境下运行它。

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

https://stackoverflow.com/questions/42055351

复制
相关文章

相似问题

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