Можно ли принять произвольный экстрактор в качестве аргумента метода

Я хотел бы повторно использовать существующие экстракторы и составить их. A => Option[B] идеально сочетается с B => Option[C],

Но я запутался, как я мог выразить такое отношение в коде.

Очевидный способ не доступен по уважительной причине:

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 _)
}

скалярный ответ:

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

Интернет говорит, что это ожидаемое поведение из-за стирания типа.

Можно ли перефразировать код, чтобы он работал правильно?

1 ответ

Тип параметра в структурном уточнении может не относиться к абстрактному типу, определенному вне этого уточнения`

Как ошибка вызвать, для structure type не могу отослать generic type что определено снаружи.

Для вашего примера вы можете использовать trait сделать то же самое, например:

trait Extractor[F, T] {
  def unapply(from: F): Option[T]
}

def bind[A, B, C](l: Extractor[A, B], r: Extractor[B, C]) = new Extractor[A, C] {
  override def unapply(from: A): Option[C] = l.unapply(from).flatMap(r.unapply)
}
Другие вопросы по тегам