Tôi dự định lọc theo một HList theo kiểu biến đổi - tôi cũng muốn bao gồm các lớp con. Vì vậy, bộ lọc covariant trên Foo
nên nắm bắt các thành phần của Foo
cũng như Bar
. Tôi đã xây dựng ví dụ này thử <:!<
, để xem nếu nó làm những gì tôi muốn nó làm.Thực hiện một bộ lọc biến đổi trên một HList
/***
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)
}
Cung cấp cho tôi
[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)
Đây sẽ là một câu hỏi hay hơn nếu bạn giải thích những gì bạn đang cố gắng làm. Trong nháy mắt, tôi không thể nói lý do tại sao bạn mong đợi hoặc 'hlistCoFilterN' để cung cấp cho bạn ví dụ bạn muốn (không phải là trường hợp' Foo =: = Bar' hoặc 'Bar <:!
@TravisBrown điểm tốt. – Reactormonk
Ah, bạn không muốn kiểm tra 'l.covariantFilter [Foo]', sau đó? –