简体   繁体   中英

existential types

(UPDATE: simplified the code and also show why it should work)

How can I fix this code?:

case class Sub[B <: Seq[_] : Manifest](b: B) {
  def foo[B2 >: B <: Seq[_] : Manifest](other: Sub[B2]) : B2 =  {
    println(manifest[B])
    println(manifest[B2])

    // next line doesn't compile 
    // other.b ++ b
    other.b 
  }

}

If I uncomment the line other.b ++ b I get the error:

<console>:13: error: Cannot construct a collection of type That with elements of type Any based on a collection of type Repr.
           other.b ++ b
                   ^

If I comment, the code compiles and running it:

scala> Sub(List(1,2)).foo(Sub(Seq(4,5)))
scala.collection.immutable.List[Int]
scala.collection.Seq[Int]
res0: Seq[Int] = List(4, 5)

So the compiler knows that the elements are of type List[Int] and Seq[Int] . It should have no problem concatenating them.

Note: I want to retain the use of 'B2 >: B' as I need it to be inferred.

You've lost the types of Seq[_] by this point, so the only possible B you can get is Seq[Any]... As such, you can ascribe b to Seq[Any] safely (b: Seq[Any]) ++ b2.

Just because you retained B in B <: Seq[_] does not mean that you can recover the existential type from the sequence.

If you're not tied to using an existential type, this should work:

case class Sub[T, B[X] <: Seq[X]](b: B[T]) {
  def foo[B2[X] <: Seq[X]](other: Sub[T,B2]) =
     other.b ++ b
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM