Reputation: 18991
Why does the following code returns Any
instead of Double
type, while all match cases return double?
trait A
case class B() extends A
case class C() extends A
def someMethod(o: Option[A]): Double = {
o.map(v => {
case B => 1.3
case C => 1.2
case others => 2.3
}).getOrElse(0.0)
// Expression of type Any doesn't conform to expected type Double >
}
Upvotes: 1
Views: 1249
Reputation: 48420
Simplifying the problem, consider the following invalid syntax
val f: String => Double = x => { case v => 3.14 }
This does not compile because expression containing cases
clauses without prior match
{ case v => 3.14 }
expands to function
y => y match { case v => 3.14 }
hence f
expands to something like
val f: String => Double = x => (y => y match { case v => 3.14 })
where we see that instead of String => Double
we are attempting String => (? => Double)
and we do not have enough information to infer what type should ?
be.
Hence the correct use of the syntax is
val f: String => Double = { case v => 3.14 }
where we note the absence of explicit x =>
.
Refer to SLS 8.5 Pattern Matching Anonymous Functions for precise specification.
Upvotes: 4
Reputation: 2734
Following up from my comments.Fixing the code to allow map to compile...
If you want to match on types you can do something like this
trait A
case class B() extends A
case class C() extends A
def someMethod(o: Option[A]): Double = o.map{
case _ : B => 1.3
case _ : C => 1.2
case _ => 2.3
}.getOrElse(0.0)
Working Scastie
Another option if these are your final definitions is using case objects
in which case you can do what you were doing
trait A
case object B extends A
case object C extends A
def someMethod(o: Option[A]): Double = o.map{
case B => 1.3
case C => 1.2
case _ => 2.3
}.getOrElse(0.0)
Keep in mind that you are still limited in things you can do in pattern matching because of the type erasure
Upvotes: 3