[英]why I cannot use FieldType as a type in a val
我正在閱讀第 5.2 章https://books.underscore.io/shapeless-guide/shapeless-guide.html#fn4的類型標記和幻像類型
我試過這個:
val tmp: FieldType["foo", Int] = "foo" ->> 12
但它給了我錯誤:
type mismatch;
found : Int(12)
required: shapeless.labelled.KeyTag["foo",Int] with Int
見https://scastie.scala-lang.org/f20gxWzcQk21GBv8JDyVog
但是,我可以通過FieldType[K, V]
的參數類型將"foo" ->> 12
val 傳遞為:
def getFieldName[K, V](value: FieldType[K, V])(implicit witness: Witness.Aux[K]): K = witness.value
def getFieldValue[K, V](value: FieldType[K, V]): V = value
getFieldName("foo" ->> 12) // gives me foo
getFieldValue("foo" ->> 12) // gives me 12
有人可以解釋為什么val tmp: FieldType["foo", Int]
不起作用嗎? 它不起作用,因為我試圖將幻像類型用作常規類型?
另一個奇怪的事實是
val tmp: 12 = "foo" ->> 12
or
val tmp: Int = "foo" ->> 12
工作正常。
我在 scala 2.13.8 和 shapeless 2.4.0-M1 中運行它
事實上,如果你沒有指定變量的類型,它就會被正確推斷
val tmp = "foo" ->> 12
tmp: FieldType["foo", Int]
但如果你這樣做了,那就是類型不匹配錯誤
val tmp: FieldType["foo", Int] = "foo" ->> 12 // found: Int(12), required: KeyTag["foo",Int] with Int
同時,如果你使用field
那么代碼編譯
val tmp: FieldType["foo", Int] = field["foo"](12)
這似乎只是一個類型推斷問題(而不是無形問題),因為
val tmp: FieldType["foo", Int] = "foo" ->>[Int] 12
編譯。
在隱式解析和宏擴展"foo" ->> 12
脫糖成SingletonOps.instance["foo"](Witness.mkWitness["foo"]("foo".asInstanceOf["foo"])).->>(12)
即
new SingletonOps {
type T = "foo"
val w = new Witness {
type T = "foo"
val value = "foo".asInstanceOf["foo"]
}
val witness: w.type = w
}.->>(12)
(Scala 2.13.8,無形 2.3.9)
這是演示此類型推斷問題的最小化代碼(純 Scala,獨立於 Shapeless,我刪除了Witness
,沒有宏和隱式)
type FieldType[K, +V] = V with KeyTag[K, V]
trait KeyTag[K, +V]
def field[K] = new FieldBuilder[K]
class FieldBuilder[K] {
def apply[V](v : V): FieldType[K, V] = v.asInstanceOf[FieldType[K, V]]
}
trait SingletonOps {
type T
def ->>[V](v: V): FieldType[T, V] = field[T](v)
}
val tmp: FieldType["foo", Int] = new SingletonOps {
type T = "foo"
}.->>/*[Int]*/(12) // found: Int(12), required: KeyTag["foo",Int] with Int
但是如果我們取消注釋[Int]
然后代碼編譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.