Given
trait A
case class B extends A
trait C
I'm trying to implement something akin to this:
val m = scala.collection.mutable.HashMap[String, C=>Option[A]](
... //some pre-defined mappings
).withDefaultValue((_:C) => None)
This will give me a type mismatch:
expected: C=>Option[A], actual: C=>None.type
I heard scala expects None to be returned from a catch clause, so I tried the very ugly
val m = scala.collection.mutable.HashMap[String, C=>Option[A]](
... //some pre-defined mappings
).withDefaultValue((_:C) => try {
throw new RuntimeException()
Some(B())
} catch{ case _ => None}
)
But that (thankfully) didn't work either:
type mismatch, expected: C=>Option[A], actual: C=>Option[B]
What's the proper way to do what I am trying to?
None
is an instance of Option[Nothing]
. But Option
is covariant in its type parameter, and Nothing
is a subtype of everything.
This means that None
is a subtype of Option[A]
. Just say so:
None: Option[A]
But type inference can usually do it for you. If you create the function in advance,
val default = (c: C) => None
then you'll get the wrong return type and need to specify it, but withDefaultValue
should already know the type of your map.