实现monad时的泛型问题

时间:2014-02-07 04:05:45

标签: scala monads

我在SO上看到了以下代码。但问题是它的mapflatMap定义并不完全正确。 map必须能够转换monadic容器/上下文的内部值,并且flatMap应该获取值,转换它并将其放回monadic上下文/容器中。在下面的示例中,它采用A并提供AM[A](而不是A->BA->M[B]

trait Mine[A] {
  def get(): A
  def map(f: A => A): Mine[A]
  def flatMap(f: A => Mine[A]): Mine[A]
}

case class Attempt1[A, B](a: (A, B)) extends Mine[(A, B)] {
  def get(): (A, B) = a
  def map(f: ((A, B)) => (A, B)): Mine[(A, B)] = {
   Attempt1(f(a._1, a._2))
  }
  def flatMap(f: ((A, B)) => Mine[(A, B)]): Mine[(A, B)] = {
   f(a._1, a._2)
  }
}

所以我想改变它,这就是我被卡住的地方。以下代码由于所有正确的原因而失败,但有人可以指导如何实现类似的东西吗?

trait Opt[A] {
 def map[B](f: A => B): Opt[B]
 def flatMap[B](f: A => Opt[B]): Opt[B]
}

case class Osome[A, B](a: (A, B)) extends Opt[(A, B)] {
 def flatMap[C, D](f: ((A, B)) => Opt[(C,D)]): Opt[(C, D)] = {
  f(a._1, a._2)
 }
 def map [C, D] (f: ((A, B)) => (C, D)): Opt[(C, D)] = {
  Osome(f(a._1, a._2))
 }

}

1 个答案:

答案 0 :(得分:1)

问题是,您未在map课程中实施flatMap的{​​{1}}和Opt方法,但是您会超载它们。在你的特性中,它们都有一个类型参数,但在你的实现中它们有两个。除此之外,您的Osome无论如何也不会是monad,因为它限制了Osomemap的结果类型,其中monad允许任意类型。