由foldRight过滤的HList不提供实例

时间:2015-07-23 09:28:43

标签: scala shapeless hlist

我正在使用libraryDependencies += "com.chuusai" %% "shapeless" % "2.2.4"

目前我有像

这样的模型HList类型
sealed trait Section
case class Header(...) extends Section
case class Customer(...) extends Section
case class Supplier(...) extends Section
case class Tech(...) extends Section
type ContractView = Header :: (Customer :: Supplier :: HNil) :: Tech :: HNil

在我的用户代码中,我想根据提议in this answer过滤使用foldRight无法查看的技术部分:

trait collectAllRF extends Poly2 {
  implicit def atAny[L <: HList, X] = at[X, L](_ :: _)
}

object collectVisRF extends collectAllRF {
  implicit def atInvis[L <: HList, S <: Section : InvisibleSection] = at[S, L]((_, l) => l)
}

例如,定义了:

trait InvisibleSection[S <: Section]
implicit object _techisInvisible extends InvisibleSection[Tech]

折叠工作正常,但我突然无法在此对象上使用filtermap,例如此代码:

val filtered = view.foldRight(HNil)(collectVisRF)
view.filter[Header] 

产生编译错误:

  

错误:无法找到参数分区的隐含值:   shapeless.ops.hlist.Partition [不成形。:: [页眉,不成形。:: [shapeless.::[Customer,shapeless.::[Supplier,shapeless.HNil]],shapeless.HNil.type]],Header]

虽然这个

view.filter[Header]

和这个

val h = view.select[Header] 
val l = view.select[Customer::Supplier::HNil]
val c = l.select[Customer]
val s = l.select[Supplier]
val manual = h :: (c :: s :: HNil) :: HNil
manual.filter[Header]

编译确定

最近我在HNil.type的结果类型末尾找到了foldRight,并将我的过滤器定义更改为

view.foldRight(HNil.asInstanceOf[HNil])(collectVisRF)

一切正常

这是预期的行为,如果是,为什么没有一些

val hNil: HNil = HNil

在图书馆?

1 个答案:

答案 0 :(得分:4)

您的最终修复几乎是,但不完全正确。而不是asInstanceOf你应该使用类型归属,

view.foldRight(HNil: HNil)(collectVisRF)

关于为什么没有定义hnil值的定义为HNil而不是HNil.type的问题是一个很好的问题。无形状与典型的Scala库不同之处在于它大量使用了包含HNil.type的单例类型,因此当前情况并不像Scala标准库中{{1}的相应情况那样明显错误和None.type几乎从不需要。

然而,您在问题中描述的情况比我想要的更频繁,所以它显然是一个真正的问题。我认为有两个hnil值太混乱了,一个类型比另一个更精确,所以问题归结为:如果Nil.type(类型)被推断为现有的东西会破坏多少类型为HNil(值),而不是现在的HNil

随时在Github上的无形状问题跟踪器中打开一张机票进行调查,如果您想尝试一下,请执行以下操作: - )