2014-03-04 94 views
2

下面的代碼編譯A [B [C]]類型Scala中即嵌套類型構造

case class A(s:Int) 
case class B(s:Int) 
case class Box[T](t:T) 

object DoublyNestedTypes extends App { 
    println("hello") 
    val l=List(Box(A(1))) 
    val l2=Box(A(2))::l 
    println(l2) 
    val l3=Box(B(1))::l2 
    println(l3)  
} 

和生產:

hello 
List(Box(A(2)), Box(A(1))) 
List(Box(B(1)), Box(A(2)), Box(A(1))) 

有人能解釋什麼是這裏嗎? 爲什麼編譯不會失敗?或者在運行時執行?

我期待這個失敗以來l類型爲List[Box[A]],而 的Box(B(1))類型是Box[B],所以我怎麼能在前面加上Box[B]List[Box[A]]

l3現在是什麼類型?

這是否必須做類型擦除?

Haskell編譯時等效代碼會失敗嗎? (我的感覺是它會。)

+1

這是基於子類型的。可比較的Haskell代碼會是一些涉及存在或數據超級的東西。 SupB B'型結構 – jozefg

回答

7

具有A類型的值aB類型的元素列表l當,a :: l不會失敗但產生List[C]類型的一個列表,其中C最小上界類型AB - 也就是它們最具體的常見超類型。如果類型AB完全不相關,則只會得到List[Any]。這是由::運營商的簽名反映(a :: l相當於l.::(a)):

sealed abstract class List[+A] { 
    def ::[B >: A] (x: B): List[B] = ... 
} 

你是正確的,這樣的事情不會在Haskell編譯,這是僅僅是因爲作爲在Haskell亞型沒有這樣的事情,所以至少上界的概念沒有任何意義。

斯卡拉這樣做是好還是不好,這是一個非常有爭議的問題。