是否有关于Obj
模块的文档?我只能找到list of functions without any description ...
(顺便说一句:我知道这些是通常不常用的低级功能)
答案 0 :(得分:17)
是的,它显然是故意无证的。对于Obj
的五种用法,我看到(或写自己,这更令人不安),其中两种是不合理的,其中两种是避免更有用的清洁设计变更的方法,其中一种是解决复杂问题的真正“好方法”。
Obj
仅公开允许探索和操纵OCaml数据的运行时表示的类型中断操作。您不需要这些函数的文档,它们很明显,但您需要了解OCaml数据表示(我使用this document了解它,但the ocaml manual也记录它),如果您需要要入侵它,你应该知道运行时知道什么是安全的,什么不是。作为一般规则:不要。
以下是Obj的一些合法用法:
将Coq程序编译为OCaml程序时; Coq类型系统功能更强大,它可以键入OCaml拒绝的内容,因此Coq-> Ocaml转换器会插入Obj.magic
调用以强制OCaml接受其输出。
在OCaml 3.x中编码GADT时,它不支持它 - 它们被添加到4.00。有一个模块级相等和函子的编码(参见this post或this work),但更常见的一个(在menhir解析器生成器中使用,它是ocamlyacc的一个很好的替代品,见this paper (PDF))使用Obj.magic
使用某种(自制)运行时类型信息编组数据时。 OCaml的Marshal
模块已经不是类型安全的(出于显而易见的原因),并且如果您需要在不同的上下文中进行不同类型的编组(例如,来自/来自SQL服务器的查询和结果,就像我在我的macaque项目中,您将需要某种不安全的演员。
答案 1 :(得分:10)
模块Obj
基本上处理堆中OCaml值的结构和解释。如果您想了解这意味着什么,您必须阅读chapter 18 of the OCaml manual,“将C与Objective Caml连接”。
这是无证的原因有两个:首先,功能是非常不安全的。只有没有类型为'a -> 'b
的总函数,所以你可以看到Obj.magic
如果要返回任何东西就必须做很多。事实上,它只是进入类型系统的一个洞,一个“杀死它的许可证”。其次,该模块允许你随意窥视和戳入堆中,实际上提供了C指向void的道德等价物。这与无限制的演员表一起让你可以从OCaml 做你想做的任何事情。
但Obj
有合法用途。我在来源中计算了超过100次Obj.magic
次,最明显的是Printf
和Scanf
的代码。另一个合法用途是尾递归列表操作,如果您可以证明代码是类型安全且线程安全的。
如果您不介意自我插件,here is an example包含在安全界面中的不安全操作,以及证明(“因为每个步骤的利弊细胞都是新鲜的......”)这确实是安全的,here is another。
答案 2 :(得分:3)
您将找不到这些功能的任何文档。如果你想使用它们,我不会重复这一点,我们不鼓励你,你必须阅读并理解它们的实现。但是我记得,其中三个被实现为“%identity”,所以这并不像看起来那么难。