Question

I have:

val foo = Some(List(1, 2, 3)) -> Some("y")

I would like to cast match it:

foo match {
    case (Some(x), Some(y)) => println(x + " " + y)
    case _ => println("error")

This works fine for Some(List(1, 2, 3) -> Some("score")) but fails for Some(List(1, 2, 3) -> None, None -> Some("y") or None -> None with:

error: constructor cannot be instantiated to expected type;
     found   : Some[A]
     required: None.type
error: not found: value ...

Why is that?

Of course I could use getOrElse() but that does not look so elegant.

Thx a lot, Karsten

Update:

foo match {
 case (x: Some[List[Int]], y: Some[Int]) => println(x.get)
 case _ => println("error")
}

Fails as well with:

error: pattern type is incompatible with expected type;
 found   : Some[Int]
 required: None.type

I would think that case _ would take care of that.

Was it helpful?

Solution

It is the compiler telling you something. If you have an expression like

val foo = Some(List(1, 2, 3)) -> None

It will have the type (Some[List[Int]], None.type), which you can easily see from typing in the expression in the scala console

scala> val foo = Some(List(1, 2, 3)) -> None
foo: (Some[List[Int]], None.type) = (Some(List(1, 2, 3)),None)

So you know at compile time that the second element of the tuple can only ever be None, a match with Some can never succeed. Hence the error message.

If you give foo a less restrictive type it will work.

val foo : (Option[List[Int]], Option[String]) = Some(List(1, 2, 3) -> None

Note that this is exactly as it should be. Matching on something that can never happen is almost definitely an error. You have to upcast to any to avoid the compile time error (but then you will get a runtime error.

OTHER TIPS

In the code below, Scala will get a compilation error on foo match but compiles and runs correctly with foo2/foo3:

val foo = None -> None
val foo2: (Option[Any], Option[Any]) = None -> None
val foo3: (Option[Any], Option[Any]) = foo

foo match {
  case (Some(x), Some(y)) => println(x + " " + y)
  case _ => println("error")
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top