[英]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.