Back to Scala3

E127: Not An Extractor

docs/_docs/reference/error-codes/E127.md

3.8.43.2 KB
Original Source

E127: Not An Extractor

This error occurs when attempting to use a type as an extractor in a pattern match, but the type lacks an appropriate unapply or unapplySeq method.

In Scala, pattern matching with extractor syntax (like case Foo(x)) requires the type to have an unapply or unapplySeq method. Case classes automatically get these methods, but regular classes do not.

An unapply method should be in an object, take a single explicit term parameter, and:

  • If it is just a test, return a Boolean. For example case even()
  • If it returns a single sub-value of type T, return an Option[T]
  • If it returns several sub-values T1,...,Tn, group them in an optional tuple Option[(T1,...,Tn)]

Additionally, unapply or unapplySeq methods cannot take type parameters after their explicit term parameter.

Sometimes, the number of sub-values isn't fixed and we would like to return a sequence. For this reason, you can also define patterns through unapplySeq which returns Option[Seq[T]]. This mechanism is used for instance in pattern case List(x1, ..., xn).


Example

scala
class Box(val x: Int)

def example(a: Any) = a match
  case Box(x) => ()

Error

scala
-- [E127] Pattern Match Error: example.scala:4:7 -------------------------------
4 |  case Box(x) => ()
  |       ^^^
  |Box cannot be used as an extractor in a pattern because it lacks an unapply or unapplySeq method with the appropriate signature
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | An unapply method should be in an object, take a single explicit term parameter, and:
  |   - If it is just a test, return a Boolean. For example case even()
  |   - If it returns a single sub-value of type T, return an Option[T]
  |   - If it returns several sub-values T1,...,Tn, group them in an optional tuple Option[(T1,...,Tn)]
  |
  | Additionaly, unapply or unapplySeq methods cannot take type parameters after their explicit term parameter.
  |
  | Sometimes, the number of sub-values isn't fixed and we would like to return a sequence.
  | For this reason, you can also define patterns through unapplySeq which returns Option[Seq[T]].
  | This mechanism is used for instance in pattern case List(x1, ..., xn)
   -----------------------------------------------------------------------------

Solution

scala
// Use a case class which automatically provides an unapply method
case class Box(x: Int)

def example(a: Any) = a match
  case Box(x) => x
  case _ => 0
scala
// Alternative: Define an explicit companion object with an unapply method
class Box(val x: Int)

object Box:
  def unapply(box: Box): Option[Int] = Some(box.x)

def example(a: Any) = a match
  case Box(x) => x
  case _ => 0
<!-- SOURCE-ONLY: Remove the notice below once this page has been manually updated. --> <aside class="warning"> This reference page was created with LLM assistance - the description of the error code may not be accurate or cover all possible scenarios. </aside>