我在SO上看到了以下代码。但问题是它的map
和flatMap
定义并不完全正确。 map
必须能够转换monadic容器/上下文的内部值,并且flatMap
应该获取值,转换它并将其放回monadic上下文/容器中。在下面的示例中,它采用A
并提供A
或M[A]
(而不是A->B
或A->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))
}
}
答案 0 :(得分:1)
问题是,您未在map
课程中实施flatMap
的{{1}}和Opt
方法,但是您会超载它们。在你的特性中,它们都有一个类型参数,但在你的实现中它们有两个。除此之外,您的Osome
无论如何也不会是monad,因为它限制了Osome
和map
的结果类型,其中monad允许任意类型。