I'd like to reuse existing extractors and compose them. A => Option[B]
perfectly matches with B => Option[C]
.
But I'm confused, how could I express such relation in code.
The obvious way is not available for a good reason:
type Extractor[F,T] = {
def unapply(from : F) : Option[T]
}
def bind[A,B,C](l : Extractor[A,B], r : Extractor[B,C]) = new {
def unapply(from : A) : Option[C] = l.unapply(from).flatMap(r.unapply _)
}
scalac reply:
Extractors.scala:7: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
def unapply(from : A) : Option[C] = l.unapply(from).flatMap(r.unapply _)
^
Extractors.scala:3: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
def unapply(from : F) : Option[T]
^
two errors found
Internet says it is expected behaviour due to type erasure.
Is it possible to rephrase the code so it would work properly?
As the error call out, for
structure type
can't refer thegeneric type
that defined in outside.For your example, you can use
trait
to do the same thing, like: