B是A的超类,然后根据scala变体和协变量。变量类型可以出现在参数中,协变类型可以出现在函数返回类型
我的scala类make方法在参数中采用B类型并返回子类型A作为函数类型但是根据函数“make”它是正确的但是如果我有类似于类的案例类的伴随类,它在A中是通用的错误。我花了足够的时间来纠正这个错误,但却无法做到这一点。
sealed class myList[+A] {
def apply[A](as: A*): myList[A] ={
if (as.isEmpty) Nil
else Cons(as.head, apply(as.tail: _*))
}
def head():A = this.head
def tail():myList[A] = this.tail
def isEmpty():Boolean ={
this match {
case Nil => true
case _: myList[A] => false
}
}
def preappend[B>:A](x: B): myList[A] ={
if (isEmpty) make(x)
else make(x)
}
def append[B>:A](x: B): myList[A] ={
if (this.isEmpty) make(x)
else Cons(this.head,this.tail.append(x))
}
def print()={
this.map(println)
}
def make[B>:A](x:B): myList[A] ={
this match {
case Nil => Cons(x,Nil)
case Cons(xh, xs) => Cons(xh, xs.make(x))
}
}
def map[A,B](f: (A) => B): myList[B] = {
this match {
case Nil => Nil
case Cons(xh:A, xs:myList[A]) => Cons(f(xh),xs.map(f ))
}
}
/**
* Combines all elements of this list into value.
*
* Time - O(n)
* Space - O(n)
*/
def fold[B](n: B)(op: (B, A) => B): B = {
def loop(l: myList[A], a: B): B =
if (l.isEmpty) a
else loop(l.tail, op(a, l.head))
loop(this, n)
}
def foldLeft[B](z: B)(f: (B, A) => B): B = {
var acc = z
var these = this
while (!these.isEmpty) {
acc = f(acc, these.head)
these = these.tail
}
acc
}
def foldRight[B,A](z: B)(f: (A, B) => B): B = this match {
case nil=> z
case Cons(x:A,xs:myList[A])=>f(x, foldRight(z)(f))
}
def length[B>:A](lst:myList[B]):Int={
this.foldRight(0) {( lst:myList[A],x:Int) => lst match{
case nil=>x
case _: myList[B] => x+1
}
}
}
def fail(m: String) = throw new NoSuchElementException(m)
}
case object Nil extends myList[Nothing] {
override def head: Nothing = fail("An empty list.")
override def tail: myList[Nothing] = fail("An empty list.")
override def isEmpty: Boolean = true
}
case class Cons[-A](head: A, tail: myList[A]) extends myList[A] {
override def isEmpty: Boolean = false
}
case class truck(
numberPlate:String
)
object Main {
def main(args: Array[String]) {
val a= new truck("1233bsd")
val b = new truck("dsads334")
val c = new myList[truck]
c.append(a)
c.print()
c.append(b)
c.print()
}
}
我得到的错误: -
mylist-v2.scala:40: error: type mismatch;
found : x.type (with underlying type B)
required: A
case Nil => Cons(x,Nil)
^
mylist-v2.scala:50: warning: abstract type pattern A is unchecked since it is eliminated by erasure
case Cons(xh:A, xs:myList[A]) => Cons(f(xh),xs.map(f ))
^
mylist-v2.scala:50: warning: abstract type A in type pattern myList[A] is unchecked since it is eliminated by erasure
case Cons(xh:A, xs:myList[A]) => Cons(f(xh),xs.map(f ))
^
mylist-v2.scala:79: warning: abstract type pattern A is unchecked since it is eliminated by erasure
case Cons(x:A,xs:myList[A])=>f(x, foldRight(z)(f))
^
mylist-v2.scala:79: warning: abstract type A in type pattern myList[A] is unchecked since it is eliminated by erasure
case Cons(x:A,xs:myList[A])=>f(x, foldRight(z)(f))
^
four warnings found
one error found
答案 0 :(得分:1)
我认为编译此代码的最小更改是将Cons
更改为
case class Cons[+A](override val head: A, override val tail: myList[A]) extends myList[A] {
以及prepend
,append
和make
至
def preappend[B>:A](x: B): myList[B] ={
def append[B>:A](x: B): myList[B] ={
def make[B>:A](x:B): myList[B] ={
由于你没有描述你的实际目标,很难说这是否是你真正想要的。