数据中的<cycle>是什么?
What is <cycle> in data?
(我用的是OCaml 4.02.3版本)
我定义了一个类型self
# type self = Self of self;;
type self = Self of self
及其实例s
# let rec s = Self s;;
val s : self = Self <cycle>
因为OCaml is a strict language,我预计定义s
会陷入无限递归。但是解释器说 s
有一个值,它是 Self <cycle>
.
我也对s
应用了一个函数。
# let f (s: self) = 1;;
val f : self -> int = <fun>
# f s;;
- : int = 1
似乎 s
在函数应用之前没有被评估(就像在非严格语言中)。
OCaml 如何处理像 s
这样的循环数据? Self <cycle>
是正规形式吗?
OCaml 确实是一种急切的语言,但是 s
是一个完全有效且经过充分评估的术语,恰好包含一个循环。例如,此代码产生预期结果:
let f (Self Self x) = x
f s == s;;
更准确地说,具有 n 个参数的构造函数的内存表示被装箱并读取如下:
⋅—————————————————————————————————————————————⋅
| header | field[0] | field[1] | ⋯ | fiekd[n] |
⋅—————————————————————————————————————————————⋅
header 包含元数据,而 field[k]
是一个 OCaml 值,即整数或指针。在 s
的情况下,Self
只有一个参数,因此只有一个字段 field[0]
。 field[0]
的值只是指向块开头的指针。因此,术语 s
在 OCaml 中可以完美表示。
此外,顶层打印机能够检测到这种循环并打印一个<cycle>
以避免在打印s
的值时陷入无限递归。在这里,<cycle>
和<abstr>
或<fun>
一样,只是表示一种顶层打印机无法打印的值。
但是请注意,循环值在很多情况下会触发无限递归,例如f s = s
,其中(=)
是结构等式
而不是物理 (i.e. (==))
触发这种递归,另一个例子是
let rec ones = 1 :: ones;; (* prints [1;<cycle>] *)
let twos = List.map ((+) 1) ones;; (* falls in an infinite recursion *)
(我用的是OCaml 4.02.3版本)
我定义了一个类型self
# type self = Self of self;;
type self = Self of self
及其实例s
# let rec s = Self s;;
val s : self = Self <cycle>
因为OCaml is a strict language,我预计定义s
会陷入无限递归。但是解释器说 s
有一个值,它是 Self <cycle>
.
我也对s
应用了一个函数。
# let f (s: self) = 1;;
val f : self -> int = <fun>
# f s;;
- : int = 1
似乎 s
在函数应用之前没有被评估(就像在非严格语言中)。
OCaml 如何处理像 s
这样的循环数据? Self <cycle>
是正规形式吗?
OCaml 确实是一种急切的语言,但是 s
是一个完全有效且经过充分评估的术语,恰好包含一个循环。例如,此代码产生预期结果:
let f (Self Self x) = x
f s == s;;
更准确地说,具有 n 个参数的构造函数的内存表示被装箱并读取如下:
⋅—————————————————————————————————————————————⋅
| header | field[0] | field[1] | ⋯ | fiekd[n] |
⋅—————————————————————————————————————————————⋅
header 包含元数据,而 field[k]
是一个 OCaml 值,即整数或指针。在 s
的情况下,Self
只有一个参数,因此只有一个字段 field[0]
。 field[0]
的值只是指向块开头的指针。因此,术语 s
在 OCaml 中可以完美表示。
此外,顶层打印机能够检测到这种循环并打印一个<cycle>
以避免在打印s
的值时陷入无限递归。在这里,<cycle>
和<abstr>
或<fun>
一样,只是表示一种顶层打印机无法打印的值。
但是请注意,循环值在很多情况下会触发无限递归,例如f s = s
,其中(=)
是结构等式
而不是物理 (i.e. (==))
触发这种递归,另一个例子是
let rec ones = 1 :: ones;; (* prints [1;<cycle>] *)
let twos = List.map ((+) 1) ones;; (* falls in an infinite recursion *)