scala - 为什么 Scala 允许嵌套数据结构,如 List 或 Array

标签 scala ocaml typing

为什么像 Scala 这样具有非常强大的静态类型系统的语言允许以下结构:

 scala> List(1, List(1,2))
 res0: List[Any] = List(1, List(1, 2))

如果你替换 List,同样的事情也会起作用与 Array .我在 OCaml 中学习了函数式编程,它会在编译时拒绝相同的代码:
# [1; [1;2]; 3];;
Characters 4-9:
  [1; [1;2]; 3];;
      ^^^^^
Error: This expression has type 'a list
       but an expression was expected of type int

那么为什么 Scala 允许它编译呢?

最佳答案

tl;博士

长话短说,OCaml 和 Scala 使用两种不同的类型系统:前者具有 structural typing ,后者有nominal typing ,因此它们在类型推断算法方面的表现有所不同。

充分讨论

如果您允许 nominal subtyping在您的类型系统中,这几乎就是您所得到的。

分析时List ,Scala 编译器将类型计算为列表包含的所有类型的 LUB(最小上限)。在这种情况下,Int 的 LUB和 ListAny .其他情况会产生更合理的结果:

@ List(Some(1), None)
res0: List[Option[Int]] = List(Some(1), None)
Some[Int]的LUB和 NoneOption[Int] ,这通常是您所期望的。如果这失败了,对用户来说将是“奇怪的”:
expected List[Some[Int]] but got List[Option[Int]]

OCaml 使用 structural subtyping ,因此它的类型系统在类型推断方面的工作方式有所不同。正如@gsg 在评论中指出的那样,OCaml 并没有像 Scala 那样统一类型,而是需要显式向上转换。

在 Scala 中,编译器在执行类型推断时统一类型(由于名义子类型。)

当然,使用显式类型注释可以获得更好的错误:
@ val x: List[Int] = List(1, List(1, 2))
Compilation Failed
Main.scala:53: type mismatch;
 found   : List[Any]
 required: List[Int]
}.apply
  ^

每当编译器推断 Any 时,您都会收到警告。 - 这通常是一个坏兆头 - 使用 -Ywarn-infer-any旗帜。这是 Scala REPL 的示例:
scala -Ywarn-infer-any
Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_51).
Type in expressions to have them evaluated.
Type :help for more information.

scala> List(1, List(1, 2))
<console>:11: warning: a type was inferred to be `Any`; this may indicate a programming error.
       List(1, List(1, 2))
            ^
res0: List[Any] = List(1, List(1, 2))

关于scala - 为什么 Scala 允许嵌套数据结构,如 List 或 Array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32113732/

相关文章:

java - Apache Spark 我在这里坚持了什么?

scala - 如何在 Scala 中从运行时值创建偏函数

ocaml - OCaml中的 "revised syntax"是什么?

parsing - Ocaml 语法错误 : why are parentheses enclosing (if . ..) 在函数应用程序中有必要吗?

c++ - _r 后缀是什么意思?

mysql - slick db.run 不插入操作

scala - Scala 中令人费解的类型不匹配 foldRight

ocaml - 如何在 esy 项目中使用 bucklescript 库和 rtop ?

Vim 用户,你们的右手放在哪里?

oop - 类型与接口(interface) : why typing then?