我对任何可疑的同步事先表示歉意。我正在学习一种新语言,绝对感谢您的帮助!
为了学习目的,我正在尝试设置可以与Scala的综合作用的自定义列表实现(称为"我的列表"(。在尝试执行此操作时,我遇到了一个使我难过的编译错误。
这是所讨论的代码:
sealed trait Mlist[+A] {
def map[A,B](f: A => B): Mlist[B]
def flatMap[A,B](f: A => Mlist[B]): Mlist[B]
def filter[A](f: A => Boolean): Mlist[A]
}
case object Mnil extends Mlist[Nothing] {
def map[A,B](f: A => B): Mlist[B] = {
Mnil
}
def flatMap[A, B](f: A => Mlist[B]): Mlist[B] = {
Mnil
}
def filter[A](f: A => Boolean): Mlist[A] = {
Mnil
}
}
case class Mcons[+A](head: A, tail: Mlist[A]) extends Mlist[A] {
def map[A,B](f: A => B): Mlist[B] = {
Mlist.map(this)(f)
}
def flatMap[A,B](f: A => Mlist[B]): Mlist[B] = {
Mlist.flatMap(this)(f)
}
def filter[A](f: A => Boolean): Mlist[A] = {
Mlist.filter(this)(f)
}
}
object Mlist {
def map[A,B](l: Mlist[A])(f: A => B): Mlist[B] = {
foldRight(l, Mnil: Mlist[B])((h, t) => Mcons(f(h), t))
}
def filter[A](as: Mlist[A])(f: A => Boolean): Mlist[A] = {
foldRight(as, Mnil: Mlist[A])((a, acc) => if (f(a)) Mcons(a, acc) else acc)
}
def flatMap[A, B](as: Mlist[A])(f: A => Mlist[B]): Mlist[B] = {
concat(map(as)(f))
}
}
object Mlist {
def map[A,B](l: Mlist[A])(f: A => B): Mlist[B] = {
foldRight(l, Mnil: Mlist[B])((h, t) => Mcons(f(h), t))
}
def filter[A](as: Mlist[A])(f: A => Boolean): Mlist[A] = {
foldRight(as, Mnil: Mlist[A])((a, acc) => if (f(a)) Mcons(a, acc) else acc)
}
def flatMap[A, B](as: Mlist[A])(f: A => Mlist[B]): Mlist[B] = {
concat(map(as)(f))
}
}
基本思想是具有定义我两个MLIST类实现的方法的特征。我没有为地图等重新进来实例方法,而是试图调用我的助手对象以重复使用其方法。
这是我看到的编译错误:
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:31: type mismatch;
[error] found : A(in method map) => B
[error] required: A(in class Mcons) => B
[error] Mlist.map(this)(f)
[error] ^
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:35: type mismatch;
[error] found : A(in method flatMap) => Mlist[B]
[error] required: A(in class Mcons) => Mlist[B]
[error] Mlist.flatMap(this)(f)
[error] ^
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:39: type mismatch;
[error] found : A(in method filter) => Boolean
[error] required: A(in class Mcons) => Boolean
[error] Mlist.filter(this)(f)
[error] ^
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:39: type mismatch;
[error] found : Mlist[A(in class Mcons)]
[error] required: Mlist[A(in method filter)]
[error] Mlist.filter(this)(f)
,如果它完全有用,这是(未经测试的,也许是完全功能失调的(,我最终打算实现:
def combos(list: Mlist[A]): Mlist[Mlist[A]] = {
for {
el <- list
combo <- combos(tail(list))
} yield {
setHead(el, combo)
}
}
有人可以带我了解我的编译错误的含义以及如何解决这些错误吗?
您正在遮盖Mlist
特征中定义的类型参数A
,在您的Mlist.map
,Mlist.flatMap
和Mlist.filter
方法中具有相同名称的类型参数:
sealed trait Mlist[+A] {
// ↑
// this is a type parameter named `A`
def map[A,B](f: A => B): Mlist[B]
// ↑
// this is a completely different, totally unrelated type parameter,
// confusingly also named `A`
def flatMap[A,B](f: A => Mlist[B]): Mlist[B]
def filter[A](f: A => Boolean): Mlist[A]
}
scala在错误消息中告诉您这一点,它在括号中告诉您参数的名称哪个的 A
s和 B
s的是:
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:31: type mismatch;
[error] found : A(in method map) => B
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] required: A(in class Mcons) => B
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] Mlist.map(this)(f)
[error] ^
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:35: type mismatch;
[error] found : A(in method flatMap) => Mlist[B]
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] required: A(in class Mcons) => Mlist[B]
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] Mlist.flatMap(this)(f)
[error] ^
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:39: type mismatch;
[error] found : A(in method filter) => Boolean
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] required: A(in class Mcons) => Boolean
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] Mlist.filter(this)(f)
[error] ^
[error] /Users/jb/Desktop/dev/personal/functional-programming-scala/src/main/scala/Ch3Lists.scala:39: type mismatch;
[error] found : Mlist[A(in class Mcons)]
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] required: Mlist[A(in method filter)]
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[error] Mlist.filter(this)(f)
也许,如果您到处都使用新名称并且不阴影,则错误消息会变得更加清晰:
sealed trait Mlist[+A] {
def map[B, C](f: B => C): Mlist[C]
def flatMap[D, E](f: D => Mlist[E]): Mlist[E]
def filter[F](f: F => Boolean): Mlist[F]
}
case object Mnil extends Mlist[Nothing] {
def map[G, H](f: G => H): Mlist[H] = this
def flatMap[I, J](f: I => Mlist[J]): Mlist[J] = this
def filter[K](f: K => Boolean): Mlist[K] = this
}
case class Mcons[+L](head: L, tail: Mlist[L]) extends Mlist[L] {
def map[M, N](f: M => N): Mlist[N] = Mlist.map(this)(f)
def flatMap[O, P](f: O => Mlist[P]): Mlist[P] = Mlist.flatMap(this)(f)
def filter[Q](f: Q => Boolean): Mlist[Q] = Mlist.filter(this)(f)
}
object Mlist {
def map[R, S](l: Mlist[R])(f: R => S): Mlist[S] =
foldRight(l, Mnil: Mlist[S])((h, t) => Mcons(f(h), t))
def filter[T](as: Mlist[T])(f: T => Boolean): Mlist[T] =
foldRight(as, Mnil: Mlist[T])((a, acc) => if (f(a)) Mcons(a, acc) else acc)
def flatMap[U, V](as: Mlist[U])(f: U => Mlist[V]): Mlist[V] =
concat(map(as)(f))
}
这给出以下错误消息:
<console>:24: error: type mismatch;
found : M => N
required: L => N
def map[M, N](f: M => N): Mlist[N] = Mlist.map(this)(f)
^
<console>:25: error: type mismatch;
found : O => Mlist[P]
required: L => Mlist[P]
def flatMap[O, P](f: O => Mlist[P]): Mlist[P] = Mlist.flatMap(this)(f)
^
<console>:26: error: type mismatch;
found : Q => Boolean
required: L => Boolean
def filter[Q](f: Q => Boolean): Mlist[Q] = Mlist.filter(this)(f)
^
<console>:26: error: type mismatch;
found : Mlist[L]
required: Mlist[Q]
def filter[Q](f: Q => Boolean): Mlist[Q] = Mlist.filter(this)(f)
^
我希望现在清楚地看到您的错误来自哪里。
请注意,您实际上永远不会在任何地方使用特质或类的类型参数,您始终仅使用方法的类型参数。这肯定听起来很腥;您需要实际使用这些类型参数!
sealed trait Mlist[+A] {
def map[B](f: A => B): Mlist[B]
def flatMap[B](f: A => Mlist[B]): Mlist[B]
def filter(f: A => Boolean): Mlist[A]
}
case object Mnil extends Mlist[Nothing] {
def map[A, B](f: A => B): Mlist[B] = this
def flatMap[A, B](f: A => Mlist[B]): Mlist[B] = this
def filter[A](f: A => Boolean): Mlist[A] = this
}
case class Mcons[+A](head: A, tail: Mlist[A]) extends Mlist[A] {
def map[B](f: A => B): Mlist[B] = Mlist.map(this)(f)
def flatMap[B](f: A => Mlist[B]): Mlist[B] = Mlist.flatMap(this)(f)
def filter(f: A => Boolean): Mlist[A] = Mlist.filter(this)(f)
}
object Mlist {
def map[A, B](l: Mlist[A])(f: A => B): Mlist[B] =
foldRight(l, Mnil: Mlist[B])((h, t) => Mcons(f(h), t))
def filter[A](as: Mlist[A])(f: A => Boolean): Mlist[A] =
foldRight(as, Mnil: Mlist[A])((a, acc) => if (f(a)) Mcons(a, acc) else acc)
def flatMap[A, B](as: Mlist[A])(f: A => Mlist[B]): Mlist[B] =
concat(map(as)(f))
}
顺便说一句,我认为您的抽象是错误的方式:肯定是,诸如Mlist
Singleton对象之类的外部对象应该不知道Mcons
对象的内部并操纵它们!一个对象应该知道如何操纵自己,没有其他人应该知道这一点。实际上,您的抽象是奇怪的混合在一起的: Mnil
do 知道如何处理自己,但是Mcons
对象却没有。这种方式看起来很少:
case class Mcons[+A](head: A, tail: Mlist[A]) extends Mlist[A] {
def map[B](f: A => B): Mlist[B] = foldRight(Mnil: Mlist[B])((h, t) => Mcons(f(h), t))
def flatMap[B](f: A => Mlist[B]): Mlist[B] = concat(map(f))
def filter(f: A => Boolean): Mlist[A] =
foldRight(Mnil: Mlist[A])((a, acc) => if (f(a)) Mcons(a, acc) else acc)
}
object Mlist {
def map[A, B](l: Mlist[A])(f: A => B): Mlist[B] = l map f
def filter[A](as: Mlist[A])(f: A => Boolean): Mlist[A] = as filter f
def flatMap[A, B](as: Mlist[A])(f: A => Mlist[B]): Mlist[B] = as flatMap f
}
请注意,每对的两个方法,实现方法和委托Mehod如何变得更简单?这是一个好兆头。