There should be no need whatsoever for implicits if all you want is an extractor.
To define an extractor, you make an object with an unapply method. E.g.
object MyExtractor { def unapply(value: ValueBeingMatched): Option[ExtractedValue] = { ... } }
Then you match a value using the extractor
val myValue: ValueBeingMatched = ... myValue match { case MyExtractor(extractedValue) => println(s"I got $extractedValue!") }
If you want your extractor to come back with multiple values, the unapply should return an option of tuple:
object MyExtractor { def unapply(value: ValueBeingMatched): Option[(ResultType1, ResultType2, ...)] = { ... } } val myValue: ValueBeingMatched = ... myValue match { case MyExtractor(result1, result2, ...) => ... }
I'm not clear on what you are trying to accomplish from your example code, so I'll make an example that maybe is relevant for you.
Let's say you make a custom Point class:
case class Point(x: Int, y: Int)
And you want to be able to extract points from a String. In this case, the ValueBeingMatched is a String, and the ExtractedValue is a Point. I'll also define the extractor in the Point object. As for functionality, let's assume that a string like "12,8" corresponds to a Point(12, 8).
object Point { def unapply(s: String): Option[Point] = { val parts = s.split(",") // this is just example code, so I won't handle failures, // but if it did fail, you'd return a None instead of Some Some(Point(parts(0).toInt, parts(1).toInt)) } }
Now that it's defined, you can match strings using the Point extractor:
val s = "3,4" s match { case Point(p) => // p is actually an instance of Point }
edit to respond to feedback:
In order to match directly to a string, the value being matched must already be a String. So one way would be to add a converter method e.g.
instanceOfMyType.convertToString match { case "abc" => println("Aha!") }
Or you would have to write an extractor to allow
instanceOfMyType match { case Extracted("abc") => println("Aha!") }
unapplyfunction to get my custom type.