在ocaml
或ghci
toplevels中工作时,我经常会因为缺少更好的单词,绑定值,函数,加载的模块等而构建一个重要的“上下文”。有没有办法保存所有这些并在以后重新加载它,所以我可以继续我离开的地方?或者更好的是,将整个批次转储为可以重新加载的文本文件,或者将其简单地修改为可以编译成可执行文件的代码(例如通过添加Main)?
答案 0 :(得分:11)
HOL light的用户有类似的需求,他们使用检查点程序来保存顶层的快照。请参阅caml邮件列表上的this message或this HOL tutorial的第8页。
通常,最好将定义保留为源代码,而不是二进制顶层快照。许多工具允许将.ml文件快速加载到顶层以便于实验(emacs模式等)。请参阅HOL教程中的警告:
在HOL中开发大型校样时,应始终将校对脚本保留为 一个OCaml文件准备重新加载,而不是依赖于ckpt。这将允许证明 稍后修改,由他人使用等。但是,它可以非常方便地制作 中间快照,因此您无需加载大型文件即可在证明上进一步工作。 这类似于编程中的通常情况:你应该始终保持你的 完整的源代码,但不希望每次使用时都重新编译所有源代码 代码。
答案 1 :(得分:10)
至少在OCaml中没有内置的支持。解决方案是使用rlwrap或任何其他readline包装器将输入的历史记录记录到文件中。例如:
> rlwrap -H mysession.ml ocaml
缺点是这也会记录有语法错误的输入,因此您必须清除它。请注意,默认情况下,如果在没有-H选项的情况下调用它,rlwrap会自动将输入保存在〜/ .ocaml_history中。
答案 2 :(得分:10)
在Haskell中,只需使用:e file
。这将打开标准编辑器,并允许您编辑某个文件。然后,使用:r
重新加载它。它将自动重新编译。
请注意,此后所有“ad-hoc”定义的功能都将丢失。有关更多信息,请参阅文档。
答案 3 :(得分:7)
ghci
使用haskeline作为命令行输入历史记录,因此您可以向上滚动以重复/编辑输入。您的输入历史记录通常记录在一个文件中,您可以在
ghci_history
System.Directory.getAppUserDataDirectory "ghc"
有各种命令可以探索'上下文'(:show bindings,:show modules,:def,..)但是它们的输出不足以重现你的会话(尽管无论如何都值得了解它们)。
一般来说,将ghci
会话与开放编辑器窗口结合起来的建议是合理的:如果它不仅仅是一次性定义,即使仅用于调试目的,最好将其包含在要加载的模块中进入ghci
,以便您可以重复使用它。
哦,如果按'上下文',你的意思是你想要加载的一些默认设置或模块,在每个项目的基础上,还有ghci
的{{3}}。也可以方便地定义自己的ghci
命令。
答案 4 :(得分:7)
在ocaml中,您可以构建自己的顶级。它至少解决了加载模块的问题。
http://caml.inria.fr/pub/docs/manual-ocaml/toplevel.html#sec278
ocamlmktop命令构建包含用户代码的OCaml toplevel 在初创公司预装。
ocamlmktop命令将一组.cmo和.cma文件作为参数, 并将它们与实现OCaml的目标文件链接起来 顶层。典型用途是:
ocamlmktop -o mytoplevel foo.cmo bar.cmo gee.cmo
这将创建包含OCaml的字节码文件mytoplevel 顶级系统,加上三个.cmo文件的代码。这个 toplevel是可直接执行的,由以下人员启动:
./mytoplevel
这会进入常规的顶级循环,但代码来自 foo.cmo,bar.cmo和gee.cmo已经加载到内存中,就好像 你打字了:
#load "foo.cmo";; #load "bar.cmo";; #load "gee.cmo";;
进入顶层。模块Foo,Bar和Gee不是 虽然打开了;你仍然要做
open Foo;;
你自己,如果这是你想要的。
答案 5 :(得分:5)
这一直困扰着我,所以我写了一个快速的python / expect script来重播每个ghci会话开始时的ghci_history。
它不是很精致。例如,它总是重播整个历史记录,而且可能很慢。