我有以下代码(有效):
type a = A of int
let print = ref (fun _ -> ())
let f x = !print (A x)
但是以下不起作用:
let print = ref (fun _ -> ())
type a = A of int
let f x = !print (A x)
我想知道为什么交换两行会导致代码无效。
谢谢!
编辑:运行第二个代码时出现以下错误:
Error: This expression has type a but an expression was expected of type 'a
The type constructor a would escape its scope
最佳答案
简而言之,必须在创建引用之前定义引用的类型:
当你第一次定义它时,你应该能够注释 print
的类型。
通过交换 a
和 print
的定义,最后一点变得不可能了:
let print: ( ??? -> unit) ref = ref (fun _ -> ())
type a = A of int
这里,???
应该是a
,但是类型a
还没有定义。
更准确地说,OCaml 中的类型有一个范围,以便检测本地类型何时会脱离其定义和有意义的上下文。例如
let x =
let module M = struct type t = A end in
M.A
失败并出现与第二个示例相同的错误
Error: This expression has type M.t but an expression was expected of type 'a The type constructor M.t would escape its scope
在这里,让类型 M.t
转义 x
的定义主体是不好的,因为模块 M
和类型 M.t
未在此定义之外定义。
您的示例因类似原因而失败。变量
let print = ref (fun _ -> ())
具有类型 ('_weak1 -> unit) ref
其中 '_weak1
是一个未知类型的占位符类型。但是此时引用的 future 类型应该已经存在。
因此,当您定义新类型时
type t = A of int
并尝试将此类型分配给 '_weak1
弱类型变量,
let print': (t -> unit) ref = print
类型检查器在创建类型变量 '_weak1
时提示类型 t
未定义:
Error: This expression has type ('weak1 -> unit) ref but an expression was expected of type (t -> unit) ref The type constructor t would escape its scope
同样,您的函数 f
let f x = !print (A x)
暗示 !print
的类型将是 t -> unit
并导致类似的错误:
Error: This expression has type t but an expression was expected of type 'weak1 The type constructor t would escape its scope
关于types - 以两种不同方式编写函数时 OCaml 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54856059/