Я намерен фильтровать HList ковариантным образом - я также хотел бы включить подклассы. Таким образом, ковариантный фильтр для Foo
должен захватывать элементы Foo
, а также Bar
. Я создал этот пример, опробовав <:!<
, чтобы посмотреть, делает ли он то, что мне нужно.
/***
scalaVersion := "2.11.2"
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.0.0"
)
*/
import shapeless._
final class HListOps[L <: HList](l: L) {
trait CoFilter[L <: HList, U] extends DepFn1[L] { type Out <: HList }
object CoFilter {
def apply[L <: HList, U](implicit filter: CoFilter[L, U]): Aux[L, U, filter.Out] = filter
type Aux[L <: HList, U, Out0 <: HList] = CoFilter[L, U] { type Out = Out0 }
implicit def hlistCoFilterHNil[L <: HList, U]: Aux[HNil, U, HNil] =
new CoFilter[HNil, U] {
type Out = HNil
def apply(l: HNil): Out = HNil
}
implicit def hlistCoFilter1[L <: HList, H](implicit f: CoFilter[L, H]): Aux[H :: L, H, H :: f.Out] =
new CoFilter[H :: L, H] {
type Out = H :: f.Out
def apply(l: H :: L): Out = l.head :: f(l.tail)
}
implicit def hlistCoFilter2[H, L <: HList, U](implicit f: CoFilter[L, U], e: U <:!< H): Aux[H :: L, U, f.Out] =
new CoFilter[H :: L, U] {
type Out = f.Out
def apply(l: H :: L): Out = f(l.tail)
}
}
def covariantFilter[U](implicit filter: CoFilter[L, U]): filter.Out = filter(l)
}
object Main extends App {
class Foo(val foo: Int)
class Bar(val bar: Int) extends Foo(bar)
val l = new Foo(1) :: new Bar(2) :: new Foo(3) :: new Bar(4) :: HNil
implicit def hlistOps[L <: HList](l: L): HListOps[L] = new HListOps(l)
print(l.covariantFilter[Bar] != l)
}
Дает мне
[error] /tmp/rendererbI8Iwy0InO/src/main/scala/test.scala:47: could not find implicit value for parameter filter: _1.CoFilter[shapeless.::[Main.Foo,shapeless.::[Main.Bar,shapeless.::[Main.Foo,shapeless.::[Main.Bar,shapeless.HNil]]]],Main.Bar]
[error] print(l.covariantFilter[Bar] != l)
hlistCoFilterN
даст вам нужный экземпляр (это не тот случай, когдаFoo =:= Bar
илиBar <:!< Foo
), и мне не очень интересно пытаться читать ваши мысли. - person Travis Brown   schedule 07.09.2014l.covariantFilter[Foo]
? - person Travis Brown   schedule 07.09.2014