我正在使用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]
折叠工作正常,但我突然无法在此对象上使用filter
或map
,例如此代码:
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
在图书馆?
答案 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上的无形状问题跟踪器中打开一张机票进行调查,如果您想尝试一下,请执行以下操作: - )