This is an SLC
Sketch implementation:
trait Extractor[-In, +Out]:
def unapply(scrutinee: In): Option[Out]
trait ExtractorSeq[-In, +Out]:
def unapplySeq(scrutinee: In): Option[Seq[Out]]
The idea is to allow simpler creation of extractor objects, notably through SAM-conversion[1]
In particular it would make it simpler to create custom string interpolation extractors:
case class Point(x: Double, y: Double)
abstract class Extractor[-In, +Out]:
def unapply(scrutinee: In): Option[Out]
extension (sc: StringContext)
def p: Extractor[Point, (Double, Double)] = point =>
sc.parts match
// checks if the pattern is p"$a,$b" or p"$a, $b"
case Seq("", "," | ", ", "") =>
Some((point.x, point.y))
case _ =>
throw IllegalArgumentException("The pattern was not well-formed")
Point(2, 3) match
// case p"$x$y" => x + y // IllegalArgumentException: The pattern was not well-formed
case p"$x,$y" => x + y
It would also allow extractor objects to stand out more:
class MyClass(x: Int):
// a bunch of things, but also an `unapply` method to avoid the wrapping into option (efficiency gain)
// vs
class MyClass(x: Int) extends Extractor[MyClass, Int]:
// a bunch of things, but also an `unapply` method to avoid the wrapping into option (efficiency gain)
It should probably have a smarter type than my proposal, since:
- It does not handle
Booleanreturn types - It does not handle
Somereturn types - It does not infer the
Outtype from the expression
Furthermore there is some discrepancy in the return type depending on the number of objects extracted:
0 objects: Boolean
1 object: Option[T]
2 objects: Option[(T, U)]
So we might want to make Out always take a tuple
Eventually, we could even make Extractor and ExtractorSeq (required) marker traits for extractor objects
This is definitely not my most polished proposal, but I hope we can refine it together !
I was not able to find a better source for SAM-conversion, if you know of one, please let me know ↩︎