Scala中的[B [C]]类型,即嵌套类型构造函数

时间:2014-03-04 19:01:57

标签: scala generics haskell

以下代码编译

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 个答案:

答案 0 :(得分:7)

a类型的值Al类型的元素列表B时,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中没有子类型这样的东西,所以最小上界的概念没有任何意义

Scala这样做是好还是坏是一个非常有争议的问题。