简体   繁体   中英

Type mismatch with type parameters

I have following trait:

sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]

Then I define a variable with type Branch :

val t = Branch(Branch(Leaf("S"), Leaf(2)), Leaf(99))

The code above works fine. But when I change it to:

val t = Branch[Int](Branch(Leaf("S"), Leaf(2)), Leaf(99))

The compiler complains:

Error:(41, 37) type mismatch;
 found   : String("S")
 required: Int
    val t = Branch[Int](Branch(Leaf("S"), Leaf(2)), Leaf(99))

When I determine the type on the first Branch (In this case is Int) then the nodes will inherent from parent?

What happens here is that in the case of Branch(Leaf("S"), Leaf(2)) the compiler will try to find a common type. In the case of Int and String , their supertype will be Any .

The problem is you are forcing the type in the branch definition using Branch[Int] which is invalidated by the contained Branch[Any] . Removing the [Int] will fix the compile error but you'll end up having as a result a Branch[Any] .

Let's breakdown a bit your definition:

sealed trait Tree[+A]

The + here says that type A can be covariant. I won't get into details about variance as there are lots of good articles explaining it (eg here ). Basically it means that a if String is a subtype of Any then a Tree[String] will be a subtype of Tree[Any] .

case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]

Let's first notice how A appears both in the left tree and in the right tree. So what happens when we take two trees that have different types and put them in the same branch?

val left  = Leaf(1)   // Tree[Int]
val right = Leaf("a") // Tree[String]
val tree  = Branch(left, right) // Tree[???]

Since A has to be the same in the left and right values (that's how we defined it), the compiler tries to solve this. So it asks itself: what is the first common type of Int and String ?

       Any
        ^
       / \
      /   \
     /     \
AnyVal     AnyRef
   /         \
  Int       String
   \         /
       ...

This is the type hierarchy in Scala quite simplified. It's better illustrated here . Thus, the common supertype of String and Int is Any and that's why the your tree will be a Tree[Any] .

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