0
object micro extends App {

  sealed trait FuncExpr

  sealed trait FuncSpecialize

  sealed case class Func(i:Int) extends FuncExpr
  sealed case class Cube(b:Boolean) extends FuncSpecialize

  object Cube {
    def unapply(arg:Func) : Option[Boolean] = arg match {
      case Func(i) if i == 42 => Some(true)
      case _ => None
    }
  }

  val x : FuncSpecialize = Cube(true)
  x match {
    case Cube(b) => println("Success")
  }
}

This is a minimized example in which i try to implement a custom unapply method for case class Cube together with the default unapply method. However if try to pattern match x i get the following error message which i would not expect to happen because Func and FuncSpezialize are completely different types:

Error:(19, 10) cannot resolve overloaded unapply
    case Cube(b) => println("Success")
Error:(19, 10) overloaded method value unapply with alternatives:
  (x$0: micro.Cube)Option[Boolean] <and>
  (arg: micro.Func)Option[Boolean]
 cannot be applied to (micro.FuncSpecialize)
    case Cube(b) => println("Success") 

Any idea, why this is the case?

Tilman Zuckmantel
  • 643
  • 1
  • 6
  • 18

1 Answers1

1

Since Cube is a case class, compiler generated unapply for it

  object Cube {
    // auto-generated
    def unapply(arg: Cube): Option[Boolean] = Some(arg.b)

    // custom
    def unapply(arg:Func) : Option[Boolean] = arg match {
      case Func(i) if i == 42 => Some(true)
      case _ => None
    }
  }

Now when you try to match pattern

  val x : FuncSpecialize = Cube(true)
  x match {
    case Cube(b) => println("Success")
  }

it's actually a call Cube.unapply(x). You can't apply any of unapply methods to x of type FuncSpecialize.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66