由 foldRight 过滤的 HList 不提供实例 [英] HList filtered by foldRight is not providing instances
问题描述
我正在使用 libraryDependencies += "com.chuusai" %% "shapeless" % "2.2.4"
目前我有模型 HList 类型,如
Currently i have model HList types like
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
查看的技术部分,如建议的 在这个答案中:
In my user code, i'd like to filter technical sections that are not supposed to view using foldRight
as proposed in this answer:
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]
Fold 工作正常,但突然间我无法在此对象上使用以下 filter
或 map
,例如此代码:
Fold is working correctly, but suddenly i could not use following filter
or map
on this object, so for example this code:
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]],Header]
error: could not find implicit value for parameter partition: shapeless.ops.hlist.Partition[shapeless.::[Header,shapeless.::[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]
编译正常
最近我在 foldRight
的结果类型末尾发现了很少的 HNil.type
并将我的过滤器定义更改为
Lately i've found little HNil.type
at end of foldRight
's result type and changed my filter definition to
view.foldRight(HNil.asInstanceOf[HNil])(collectVisRF)
一切正常
这是预期的行为吗,如果是,为什么没有一些
Is this an expected behaviour, and if yes why there is no some
val hNil: HNil = HNil
在图书馆?
推荐答案
您最终的修复几乎是正确的,但不完全正确.您应该使用类型归属,而不是 asInstanceOf
,
Your eventual fix is almost, but not quite, right. Rather than asInstanceOf
you should use a type ascription,
view.foldRight(HNil: HNil)(collectVisRF)
关于为什么没有定义为 HNil
而不是 HNil.type
的 hnil 值的问题是一个很好的问题.shapeless 与典型的 Scala 库不同,它大量使用单例类型,包括 HNil.type
,所以目前的情况并不像 Scala 标准库中的相应情况那样明显错误,其中 None.type
和 Nil.type
几乎是不需要的.
Your question about why there is no definition of an hnil value typed as HNil
rather than as HNil.type
is a good one. shapeless is different from typical Scala libraries in that it makes heavy use of singleton types, HNil.type
included, so the current situation isn't as obviously wrong as the corresponding situation in the Scala standard library where None.type
and Nil.type
are almost never desired.
尽管如此,您在问题中描述的情况出现的频率比我希望的要高,因此这显然是一个真正的问题.我认为有两个 hnil 值会太混乱,一个比另一个具有更精确的类型,所以问题归结为:如果 HNil
(类型)是多少现有的东西会破坏推断为 HNil
(值)的类型,而不是现在的 HNil.type
.
Nevertheless the situation you describe in your question comes up more often than I would like, so it's clearly a real problem. I think it would be too confusing to have two hnil values, one with a more precise type than the other, so the question boils down to: how much existing stuff would break if HNil
(the type) was inferred as the type of HNil
(the value) rather than HNil.type
as it is now.
请随意在 Github 上的无形问题跟踪器中打开一张票来调查此问题,如果您想尝试一下,请这样做:-)
Feel free to open a ticket in the shapeless issue tracker on Github to investigate this, and if you'd like to give it a try, please do :-)
这篇关于由 foldRight 过滤的 HList 不提供实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!