E189: Extractor Not Found
This error occurs when an extractor pattern is used with a name that does not refer to an object with an unapply or unapplySeq method.
Extractors in pattern matching require an object with an unapply or unapplySeq method that can deconstruct values. Case classes and enum cases automatically provide these extractors.
Longer explanation:
An application name(...) in a pattern can refer to an extractor which defines an unapply or unapplySeq method. Example:
object split:
def unapply(x: String) =
val (leading, trailing) = x.splitAt(x.length / 2)
Some((leading, trailing))
val split(fst, snd) = "HiHo"
The extractor pattern split(fst, snd) defines fst as the first half "Hi" and snd as the second half "Ho" of the right hand side "HiHo". Case classes and enum cases implicitly define extractors with the name of the class or enum case.
Example
def example(): Unit =
val s(): String = "hello"
Error
-- [E189] Not Found Error: example.scala:2:6 -----------------------------------
2 | val s(): String = "hello"
| ^
| no pattern match extractor named s was found
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| An application s(...) in a pattern can refer to an extractor
| which defines an unapply or unapplySeq method. Example:
|
| object split:
| def unapply(x: String) =
| val (leading, trailing) = x.splitAt(x.length / 2)
| Some((leading, trailing))
|
| val split(fst, snd) = "HiHo"
|
| The extractor pattern `split(fst, snd)` defines `fst` as the first half "Hi" and
| `snd` as the second half "Ho" of the right hand side "HiHo". Case classes and
| enum cases implicitly define extractors with the name of the class or enum case.
| Here, no extractor named s was found, so the pattern could not be typed.
-----------------------------------------------------------------------------
Solution
Use a simple value binding without parentheses:
def example(): Unit =
val s: String = "hello"
println(s)
Or if you need an extractor, define one and use it in a match:
object MyString:
def unapply(s: String): Option[String] = Some(s)
def example(): Unit =
"hello" match
case MyString(s) => println(s)