![](/img/trans.png)
[英]How to transform an HList to another HList with foldRight/foldLeft
[英]HList filtered by foldRight is not providing instances
我正在使用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
在我的用户代码中,我想按照本答案中的建议过滤不应使用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。:: [Header,shapeless。:: [shapeless。::[Customer,Shapeless。:::Supplier ,shapeless.HNil]] ,shapeless.HNil.type],头]
而这个
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]
编译确定
最近我在foldRight
的结果类型的末尾发现了一些HNil.type
,并将我的过滤器定义更改为
view.foldRight(HNil.asInstanceOf[HNil])(collectVisRF)
一切正常
这是一种预期的行为,如果是,为什么没有一些
val hNil: HNil = HNil
在图书馆?
你的最终修复几乎是,但并不完全正确。 而不是asInstanceOf
你应该使用类型归属,
view.foldRight(HNil: HNil)(collectVisRF)
关于为什么没有hnil值定义为HNil
而不是HNil.type
是一个很好的问题。 shapeless与典型的Scala库的不同之处在于它大量使用了包含HNil.type
的单例类型,因此当前情况并不像Scala标准库中的相应情况那样明显错误,其中None.type
和Nil.type
是几乎从未想过。
然而,你在问题中描述的情况比我想象的更频繁,所以这显然是一个真正的问题。 我认为有两个hnil值太混乱了,一个比另一个更精确的类型,所以问题归结为:如果HNil
(类型)被推断为HNil
的类型,现有的东西会破坏HNil
(价值)而不是现在的HNil.type
。
随意在Github上的无形问题跟踪器中打开一张票来调查此问题,如果你想尝试一下,请执行:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.