Я бы хотел создать метод, который бы использовал вектор или последовательность некоторого типа, скажем, Int, и вызывал фильтр для него.
Например:
implicit class SharedOps[F](xs: F)(implicit ev: OneOf[F, Seq[Int] ::: Vector[Int] ::: HSNil]) {
def filter(x: Int):F = xs.filter({a:Int => a == x})
}
OneOf в основном проверяет, что F является либо Seq [Int], либо Vector [Int]
Сложность в том, что я хочу, чтобы фильтр возвращал тот же тип, что и вход (например, Seq [Int] или Vector [Int]), но компилятор жалуется
error: type mismatch;
found : scala.this.Function1[scala.this.Int,scala.this.Boolean]
required: scala.this.Int
def filter(x: Int):F = xs.filter({a:Int => a == x})
Каким-то образом компилятор забыл, что я начал с коллекции сортировок, и думает, что xs - это одна вещь.
Поэтому я изменил дизайн:
implicit class SharedOps2[A,F[A]<:TraversableLike[A,A]](xs: F[A])(implicit ev: OneOf[F[A], Seq[Int] ::: Vector[Int] ::: HSNil]) {
def filter(x: A): F[A] = xs.filter({ a: Int => a == x })
}
Теперь компилятор жалуется, что: Выражение типа A не соответствует ожидаемому типу F [A]
Не уверен, как его взять отсюда. На этом этапе я бы хотел избежать создания бесформенных копроизведений.
Для полноты вот код OneOf:
sealed trait HSubset // HList
@implicitNotFound("No member of type class HSubset in scope for ${H}")
trait :::[+H, +T <: HSubset] extends HSubset // HCons ::
sealed trait HSNil extends HSubset // HNil
@implicitNotFound("No member of type class BelongsTo in scope for ${T}")
trait BelongsTo[T, U <: HSubset]
object BelongsTo {
implicit def baseCase[H, U <: HSubset]: BelongsTo[H, H ::: U] = null
implicit def recursiveCase[H, U <: HSubset, T](implicit ev: T BelongsTo U): T BelongsTo (H ::: U) = null
}
@implicitNotFound("No member of type class SubsetOf in scope for ${U} ${T}")
trait SubsetOf[U <: HSubset, T <: HSubset]
object SubsetOf {
implicit def baseCase[U1, U <: HSubset](implicit s: U1 BelongsTo U): SubsetOf[U1 ::: HSNil, U] = null
implicit def recursiveCase[U <: HSubset, T1, T <: HSubset](implicit ev1: T1 BelongsTo U, ev2: T SubsetOf U): (T1 ::: T) SubsetOf U = null
}
trait OneOf[T, U <: HSubset]
object OneOf {
implicit def baseCase[U <: HSubset, T](implicit s: T BelongsTo U): T OneOf U = null
implicit def recursiveCase[T, Ev <: HSubset, Target <: HSubset](implicit ev1: T OneOf Ev, ev2: Ev SubsetOf Target): T OneOf Target = null
}