Adelin
Adelin

Reputation: 18991

Scala match case return Any type instead of returned types by the match case

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

Answers (2)

Mario Galic
Mario Galic

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

sinanspd
sinanspd

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

Related Questions