(我使用OCaml版本4.02.3)
我定义了一个类型 self
# type self = Self of self;;
type self = Self of self
Run Code Online (Sandbox Code Playgroud)
及其实例 s
# let rec s = Self s;;
val s : self = Self <cycle>
Run Code Online (Sandbox Code Playgroud)
由于OCaml是一种严格的语言,我希望定义s会陷入无限递归。但是口译员说s确实有价值Self <cycle>。
我还将一个功能应用于s。
# let f (s: self) = 1;;
val f : self -> int = <fun>
# f s;;
- : int = 1
Run Code Online (Sandbox Code Playgroud)
似乎s未在函数应用程序之前进行评估(例如使用非严格语言)。
OCaml如何处理像循环数据s?Self <cycle>是正常形式吗?
OCaml确实是一种渴望的语言,但是它s是一个完全有效且经过充分评估的术语,恰好包含一个循环。例如,此代码产生预期的结果:
let f (Self Self x) = x
f s == s;;
Run Code Online (Sandbox Code Playgroud)
更准确地说,将具有n个参数的构造函数的内存表示形式装箱,并按以下方式读取:
?—————————————————————————————————————————————?
| header | field[0] | field[1] | ? | fiekd[n] |
?—————————————————————————————————————————————?
Run Code Online (Sandbox Code Playgroud)
标头包含元数据,而field[k]OMACl值是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 *)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
396 次 |
| 最近记录: |