簡體   English   中英

為什么我不能將 FieldType 用作 val 中的類型

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM