类型注释被推断的表达式类型覆盖

cou*_*ech 3 ocaml types scala

在 scala 编程语言中,鉴于我将用更广泛的类型注释表达式并提供一个狭窄的值,我的程序被拒绝:

scala> def x[A](): A = 8 
<console>:11: error: type mismatch;
found   : Int(8)
required: A
      def x[A]() = 8: A
Run Code Online (Sandbox Code Playgroud)

而在 ocaml 中,当我做同样的事情时,程序被接受,但表达式的类型注释被更窄的表达式类型覆盖。

utop # let x (): 'a = 8 ;;
val x : unit -> int = <fun>
Run Code Online (Sandbox Code Playgroud)

这些类型系统之间的区别是什么,导致的情况是,在一种情况下程序被拒绝,而在另一种情况下它被接受?

gle*_*nsl 7

@craigfe 实际上昨天刚刚写一篇关于这个的非常容易理解的帖子,我强烈建议阅读。

但简短的回答是 OCaml 中注释中的类型变量是统一变量,而不是多态类型约束。它们表示编译器要推断的未知类型,编译器将更喜欢更通用的解决方案并可能推断它是多态的,但如果不可能,则将其推断为特定类型。

为了获得您期望的行为,您必须明确指出类型变量应该使用 进行普遍量化'a.,通常读作“对于所有 a”:

utop # let x: 'a. unit -> 'a = fun () -> 8 ;;
                               ^^^^^^^^^^^
Error: This definition has type unit -> int which is less general than
         'a. unit -> 'a
Run Code Online (Sandbox Code Playgroud)