由 foldRight 过滤的 HList 不提供实例 [英] HList filtered by foldRight is not providing instances

查看:40
本文介绍了由 foldRight 过滤的 HList 不提供实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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 工作正常,但突然间我无法在此对象上使用以下 filtermap,例如此代码:

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.typeNil.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆