Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can scala not Infer that Left[X,A] is a reasonable subtype of Either[X,B]?

Why does this code not type check?

def foo: Either[String, List[Int]] = {  
  val x = null: Either[String, String]

  x match {
    case l @ Left(_) => l
    case Right(_) => Right(List(3))
  }
}

Specifically, why can't/doesn't the compiler reify the type of Left[A,X] and Either[A,B]?

This happened in scala 2.8.2 and scala 2.9.2

like image 945
Squidly Avatar asked Jan 16 '23 21:01

Squidly


1 Answers

There is a genuine conflict here:

Left[String, String] <: Either[String, List[Int]]

is not true. Left is typed on both left and right parameters, and even though there is no actual difference between the two (so casting would be safe), this is not what you have told the compiler. So, of course, it will complain.

There are other weaknesses in type inference in pattern matching, but this is not one of them.


Edit: one can imagine an alternate singly-parameterized implementation of Left in which

Left[String] <: Either[String, Nothing] <: Either[String, List[Int]]

which would throw away type information. Methods like swap would be tricker to use, but it would allow the pattern given by the OP. However, the type-preserving form was used in the standard implementation in Scala.

like image 199
Rex Kerr Avatar answered Feb 03 '23 20:02

Rex Kerr