scala变体类型导致错误类型不匹配错误

时间:2018-01-30 14:02:18

标签: scala generics functional-programming

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

1 个答案:

答案 0 :(得分:1)

我认为编译此代码的最小更改是将Cons更改为

case class Cons[+A](override val head: A, override val tail: myList[A]) extends myList[A] {

以及prependappendmake

的签名
def preappend[B>:A](x: B): myList[B] ={
def append[B>:A](x: B): myList[B] ={
def make[B>:A](x:B): myList[B] ={

由于你没有描述你的实际目标,很难说这是否是你真正想要的。