[英]Scala Structural type and existential type issue
我的問題是,在下面的代碼片段中,c2可以通過編譯,但t2失敗。 為什么?
type PairT[A, B] = { //structural type
type T1 = A
type T2 = B
}
class PairC[A, B] {
type T1 = A
type T2 = B
}
case class TMap[A, B](a: A, b: B)
type MapC2[A] = TMap[p.T1, p.T2] forSome { val p: PairC[A, A] }
type MapT2[A] = TMap[p.T1, p.T2] forSome { val p: PairT[A, A] }
val c2: MapC2[Int] = TMap(1,2)
val t2: MapT2[Int] = TMap(1,2)
最近我有一個有趣的scala謎語涉及存在類型和類型別名( https://softwaremill.com/scala-riddle ),我發現當類型別名不起作用時,我們應該嘗試使用有界抽象類型成員。
我還沒有弄清楚任何模式可以告訴我在特定情況下我需要應用哪種類型的成員。 我在文檔中找不到答案,也許這是一個實現細節?
我希望有人能幫助我找到這樣的模式或至少給出一些新的線索..
在PairT
內部,我用緊密有界的抽象類型( type T1 >: A <: A
)替換了類型別名( type T1 = A
),並且它起作用(scalac 2.11.4)。
更有趣的是 - PairC
,它是一個具體類,只能使用類型別名 - 如果我嘗試用有界抽象類型成員替換它們,則會引發編譯錯誤。
以下是我修改后的整個代碼:
package so1
import scala.language.existentials
object SOPuzzle {
type PairT[F, S] = {
type T1 >: F <: F
type T2 >: S <: S
}
class PairC[F, S] {
type T1 = F
type T2 = S
}
case class TMap[T, U](a: T, b: U) {
def consumeA(a: T): T = a
def consumeB(b: U): U = b
}
type MapC2[A] = TMap[p.T1, p.T2] forSome {val p: PairC[A, A]}
type MapC2V2[A] = TMap[PairC[A, A]#T1, PairC[A,A]#T2]
type MapT2[A] = TMap[p.T1, p.T2] forSome {val p: PairT[A, A]}
type MapT2V2[A] = TMap[PairT[A, A]#T1, PairT[A, A]#T2]
val c2: MapC2[Int] = TMap(1, 2)
val c2v2: MapC2V2[Int] = TMap(1, 2)
val t2: MapT2[Int] = TMap(1, 2)
val t2v2: MapT2V2[Int] = TMap(1, 2)
val i1:Int = c2.consumeA(0)
val i2:Int = c2.consumeB(0)
val i3:Int = c2v2.consumeA(0)
val i4:Int = c2v2.consumeB(0)
val i5:Int = t2.consumeA(0)
val i6:Int = t2.consumeB(0)
val i7:Int = t2v2.consumeA(0)
val i8:Int = t2v2.consumeB(0)
}
我認為這是關於type
構造的推理錯誤(或者可能是限制)。
編輯:錯誤消息是讓我覺得它是一個錯誤的第一件事:
“類型不匹配;發現:需要Int(1):A”
如果將最后一行拆分為2,即
val t3 = TMap(1,2)
val t2: MapT2[Int] = t3
,然后它產生一個類似的pongy消息:
“類型不匹配;找到:Test1.this.TMap [Int,Int] required:Test1.this.MapT2 [Int](擴展為)Test1.this.TMap [A,A]”
鑒於A是'符號'而Int是一個類,它似乎是在比較蘋果和橙子。 對不起,我不能再采取這種邏輯了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.