Back to Scala3

E108: Unapply Invalid Return Type

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

3.8.42.8 KB
Original Source

E108: Unapply Invalid Return Type

This error is emitted when an extractor's unapply or unapplySeq method has an invalid return type.

To be used as an extractor, an unapply method must return a type that either:

  • Has members isEmpty: Boolean and get: S (usually an Option[S])
  • Is a Boolean
  • Is a Product (like a Tuple2[T1, T2])

Example

scala
object MyExtractor:
  def unapply(s: String): String = s

def example(s: String) = s match
  case MyExtractor(_) => "ok"
  case _ => "no match"

Error

scala
-- [E108] Declaration Error: example.scala:5:18 --------------------------------
5 |  case MyExtractor(_) => "ok"
  |       ^^^^^^^^^^^^^^
  |   String is not a valid result type of an unapply method of an extractor.
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |
  | To be used as an extractor, an unapply method has to return a type that either:
  |  - has members isEmpty: Boolean and get: S (usually an Option[S])
  |  - is a Boolean
  |  - is a Product (like a Tuple2[T1, T2]) of arity i with i >= 1, and has members _1 to _i
  |
  | See: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html#fixed-arity-extractors
  |
  | Examples:
  |
  | class A(val i: Int)
  |
  | object B {
  |   def unapply(a: A): Option[Int] = Some(a.i)
  | }
  |
  | object C {
  |   def unapply(a: A): Boolean = a.i == 2
  | }
  |
  | object D {
  |   def unapply(a: A): (Int, Int) = (a.i, a.i)
  | }
  |
  | object Test {
  |   def test(a: A) = a match {
  |     case B(1) => 1
  |     case a @ C() => 2
  |     case D(3, 3) => 3
  |   }
  | }
  |
   -----------------------------------------------------------------------------

Solution

scala
// Return Option[T] for single value extraction
object MyExtractor:
  def unapply(s: String): Option[String] = Some(s)

def example(s: String) = s match
  case MyExtractor(x) => x
  case _ => "no match"
scala
// Or return Boolean for test-only extraction
object IsEmpty:
  def unapply(s: String): Boolean = s.isEmpty

def example(s: String) = s match
  case IsEmpty() => "empty"
  case _ => "not empty"
scala
// Or return a tuple for multiple values
object Split:
  def unapply(s: String): Option[(String, String)] =
    val mid = s.length / 2
    Some((s.take(mid), s.drop(mid)))

def example(s: String) = s match
  case Split(a, b) => s"$a | $b"
  case _ => "no match"
<!-- 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>