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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With