Search code examples
scalacase-classunapply

Unable to resolve unapply


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?


Solution

  • 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.