Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在HList上执行协变过滤器_Scala_Shapeless - Fatal编程技术网

Scala 在HList上执行协变过滤器

Scala 在HList上执行协变过滤器,scala,shapeless,Scala,Shapeless,我打算以协变的方式对HList进行过滤——我也想包括子类。因此Foo上的协变过滤器应该捕获Foo以及Bar的元素。我构建了这个示例,尝试这里有几个问题。首先,您的类型类是在扩展类内部定义的,但是您需要在调用convaratitfilter时使用实例。也许编译器可以为您找到它,但它没有。不过,无论如何,不嵌套类型类要干净得多 第二个问题是,您的两个hlistCoFilterN案例实际上并没有捕获您想要的所有内容。只有在头的类型是过滤器类型,而过滤器类型不是头类型的子类型的情况下,您才告诉编译器该怎

我打算以协变的方式对HList进行过滤——我也想包括子类。因此
Foo
上的协变过滤器应该捕获
Foo
以及
Bar
的元素。我构建了这个示例,尝试
这里有几个问题。首先,您的类型类是在扩展类内部定义的,但是您需要在调用
convaratitfilter
时使用实例。也许编译器可以为您找到它,但它没有。不过,无论如何,不嵌套类型类要干净得多

第二个问题是,您的两个
hlistCoFilterN
案例实际上并没有捕获您想要的所有内容。只有在头的类型是过滤器类型,而过滤器类型不是头类型的子类型的情况下,您才告诉编译器该怎么做。头部类型是过滤器类型的子类型的位置如何?你可能想要这样的东西:

import shapeless._

trait CoFilter[L <: HList, U] extends DepFn1[L] { type Out <: HList }

object CoFilter {
  def apply[L <: HList, U](implicit f: CoFilter[L, U]): Aux[L, U, f.Out] = f

  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[U, H <: U, T <: HList]
    (implicit f: CoFilter[T, U]): Aux[H :: T, U, H :: f.Out] =
      new CoFilter[H :: T, U] {
        type Out = H :: f.Out
        def apply(l: H :: T): Out = l.head :: f(l.tail)
      }

  implicit def hlistCoFilter2[U, H, T <: HList]
    (implicit f: CoFilter[T, U], e: H <:!< U): Aux[H :: T, U, f.Out] =
      new CoFilter[H :: T, U] {
        type Out = f.Out
        def apply(l: H :: T): Out = f(l.tail)
      }
}

implicit final class HListOps[L <: HList](val l: L)  {
  def covariantFilter[U](implicit filter: CoFilter[L, U]): filter.Out = filter(l)
}
scala> l.covariantFilter[Foo] == l
res0: Boolean = true

scala> l.covariantFilter[Bar] == l
res1: Boolean = false
您的过滤器的工作方式如下:

import shapeless._

trait CoFilter[L <: HList, U] extends DepFn1[L] { type Out <: HList }

object CoFilter {
  def apply[L <: HList, U](implicit f: CoFilter[L, U]): Aux[L, U, f.Out] = f

  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[U, H <: U, T <: HList]
    (implicit f: CoFilter[T, U]): Aux[H :: T, U, H :: f.Out] =
      new CoFilter[H :: T, U] {
        type Out = H :: f.Out
        def apply(l: H :: T): Out = l.head :: f(l.tail)
      }

  implicit def hlistCoFilter2[U, H, T <: HList]
    (implicit f: CoFilter[T, U], e: H <:!< U): Aux[H :: T, U, f.Out] =
      new CoFilter[H :: T, U] {
        type Out = f.Out
        def apply(l: H :: T): Out = f(l.tail)
      }
}

implicit final class HListOps[L <: HList](val l: L)  {
  def covariantFilter[U](implicit filter: CoFilter[L, U]): filter.Out = filter(l)
}
scala> l.covariantFilter[Foo] == l
res0: Boolean = true

scala> l.covariantFilter[Bar] == l
res1: Boolean = false

我想这就是你想要的。

如果你能解释一下你想做什么,这个问题会好得多。乍一看,我不知道你为什么希望
hlistCoFilterN
给你想要的实例(不是
Foo=:=Bar
Bar@TravisBrown都是好的观点。啊,你不想检查
l.convaratitfilter[Foo]
,那么?@TravisBrown这是应该满足要求的方法,所以我想测试它。
hlistCoFilter2
的要求是必要的吗?反正应该是默认的。你是说

scala> l.covariantFilter[Foo] == l
res0: Boolean = true

scala> l.covariantFilter[Bar] == l
res1: Boolean = false