foldRight 过滤的 HList 不提供实例
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
查看的技术部分,建议 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
,例如此代码:
val filtered = view.foldRight(HNil)(collectVisRF)
view.filter[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
,并将我的过滤器定义更改为
view.foldRight(HNil.asInstanceOf[HNil])(collectVisRF)
并且一切正常
这是预期的行为吗?如果是,为什么没有
val hNil: HNil = HNil
在图书馆?
您的最终修复几乎正确,但不完全正确。而不是 asInstanceOf
你应该使用类型归属,
view.foldRight(HNil: HNil)(collectVisRF)
关于为什么没有定义输入为 HNil
而不是 HNil.type
的 hnil 值的问题是一个很好的问题。 shapeless 与典型的 Scala 库的不同之处在于它大量使用单例类型,包括 HNil.type
,因此当前情况不像 Scala 标准库中的相应情况那样明显错误,其中 None.type
和Nil.type
几乎从不需要。
尽管如此,您在问题中描述的情况出现的频率比我希望的要高,所以这显然是一个真正的问题。我认为如果有两个 hnil 值,一个的类型比另一个的类型更精确,那会太混乱了,所以问题归结为:如果 HNil
(类型)被推断为HNil
(值)的类型,而不是现在的 HNil.type
。
欢迎在 Github 上的 shapeless 问题跟踪器中打开一个票证来调查这个问题,如果你想试一试,请做:-)
我正在使用 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
查看的技术部分,建议 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
,例如此代码:
val filtered = view.foldRight(HNil)(collectVisRF)
view.filter[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
,并将我的过滤器定义更改为
view.foldRight(HNil.asInstanceOf[HNil])(collectVisRF)
并且一切正常
这是预期的行为吗?如果是,为什么没有
val hNil: HNil = HNil
在图书馆?
您的最终修复几乎正确,但不完全正确。而不是 asInstanceOf
你应该使用类型归属,
view.foldRight(HNil: HNil)(collectVisRF)
关于为什么没有定义输入为 HNil
而不是 HNil.type
的 hnil 值的问题是一个很好的问题。 shapeless 与典型的 Scala 库的不同之处在于它大量使用单例类型,包括 HNil.type
,因此当前情况不像 Scala 标准库中的相应情况那样明显错误,其中 None.type
和Nil.type
几乎从不需要。
尽管如此,您在问题中描述的情况出现的频率比我希望的要高,所以这显然是一个真正的问题。我认为如果有两个 hnil 值,一个的类型比另一个的类型更精确,那会太混乱了,所以问题归结为:如果 HNil
(类型)被推断为HNil
(值)的类型,而不是现在的 HNil.type
。
欢迎在 Github 上的 shapeless 问题跟踪器中打开一个票证来调查这个问题,如果你想试一试,请做:-)