这是Why can't I run such scala code? (reduceRight List class method)的续集
我正在按照那里接受的答案来重命名我的抽象类并添加列表:List [T]作为方法 foldRight 的参数。
abstract class ListT {
def foldRight[U](z : U)(list: List[T], op: (T, U) => U): U = list match {
case Nil => z
case x :: xs => op(x, foldRight(z)(xs, op))
}
}
但是我仍然收到'def'行的错误
此行未找到多个标记:输入T
答案 0 :(得分:2)
让我们从头开始,这应该有助于您理解概念。
我们将创建自己的简单功能列表。
它将称为MyList
,将有一个名为MyNil
的空列表,并且cons类/运算符为:!:
。
// Here we create the type MyList.
// The sealed is used to signal that the only valid implementations
// will be part of this file. This is because, a List is an ADT.
// The A (which could be a T or whatever) is just a type parameter
// it means that our list can work with any arbitrary type (like Int, String or My Class)
// and we just give it a name, in order to be able to refer to it in the code.
// Finally, the plus (+) sign, tells the compiler that MyList is covariant in A.
// That means: If A <: B Then MyList[A] <: MyList[B]
// (<: means subtype of)
sealed trait MyList[+A] {
def head: A // Here we say that the head of a List of As is an A.
def tail: MyList[A] // As well, a tail of a List of As is another list of As.
// Here we define the cons operator, to prepend elements to the list.
// You can see that it will just create a new cons class with the new element as the head & this as the tail.
// Now, you may be wondering why we added a new type B and why it must be a super type of A
// You can check out this answer of mine:
// https://stackoverflow.com/questions/54163830/implementing-a-method-inside-a-scala-parameterized-class-with-a-covariant-type/54164135#54164135
final def :!:[B >: A](elem: B): MyList[B] =
new :!:(elem, this)
// Finally, foldRigh!
// You can see that we added a new type parameter B.
// In this case, it does not have any restriction because the way fold works.
final def foldRight[B](z: B)(op: (A, B) => B): B = this match {
case MyNil => z
case h :!: t => op(h, t.foldRight(z)(op))
}
}
object MyList {
// Factory.
def apply[A](elems: A*): MyList[A] =
if (elems.nonEmpty) {
elems.head :!: MyList(elems.tail : _*)
} else {
MyNil
}
}
// Implementations of the MyList trait.
final case class :!:[+A](head: A, tail: MyList[A]) extends MyList[A]
final case object MyNil extends MyList[Nothing] {
override def head = throw new NoSuchElementException("head of empty list")
override def tail = throw new NoSuchElementException("tail of empty list")
}
现在您可以:
val l1 = MyList(2, 3, 4) // l1: MyList[Int] = 2 :!: 3 :!: 4 :!: MyNil
val l2 = 1 :!: l1 // // l2: MyList[Int] = 1 :!: 2 :!: 3 :!: 4 :!: MyNil
val sum = l2.foldRight(0)(_ + _) // sum: Int = 10