考虑这个非常基本的模块定义:
module type My_test = sig
type config with sexp
end;;
当我在utop提示符下直接输入时,一切正常:
utop # module type My_test = sig
type config with sexp
end;;
module type My_test =
sig type config val config_of_sexp : Sexp.t -> config val sexp_of_config : config -> Sexp.t end
但是当我尝试#use
包含完全相同定义的文件时,我收到Unbound type constructor _no_unused_value_warning_
错误:
utop # #use "dummy.mli";;
File "dummy.mli", line 2, characters 7-13:
Error: Unbound type constructor _no_unused_value_warning_
(第2行是type config with sexp
)
版本信息:The universal toplevel for OCaml, version 1.7, compiled for OCaml version 4.01.0
更新:
我开始赏金,因为我真的对
感兴趣答案 0 :(得分:4)
1)ocaml顶级有两个未记录的选项:-dsource& -dparsetree
2)如果我启用-dsource然后尝试#use“dummy.mli”。我看到生成的源代码如下:
$ ocaml -dsource
# #use "dummy.mli";;
module type My_test =
sig
type config
val config_of_sexp : (Sexplib.Sexp.t -> config) _no_unused_value_warning_
val sexp_of_config : (config -> Sexplib.Sexp.t) _no_unused_value_warning_
end;;
File "dummy.mli", line 1, characters 31-37:
Error: Unbound type constructor _no_unused_value_warning_
然而,当我直接在顶层输入类型声明时,生成的源没有“_no_unused_value_warning _”
4)由于_no_unused_value_warning_的存在,为这两种情况生成的解析树略有不同。
5)经过一番greping之后,我看到type_conv库插入了''val name:_no_unused_value_warning_'作为一种停用警告的黑客行为 - https://github.com/janestreet/type_conv/blob/master/lib/pa_type_conv.ml - 从第916行开始有一条评论解释了这一点东西(我还在学习ocaml,所以我还不了解这些部分的所有内容)
由于sexplib使用type_conv,因此在这种情况下添加了此签名。
6)但是,这里真正的问题必须是ocaml toplevel如何处理#use指令和直接输入的代码行。
在此文件中:https://github.com/diml/ocaml-3.12.1-print/blob/master/toplevel/opttoploop.ml - use_file(在第316行)使用List.iter循环遍历Parsetree.toplevel_phrase列表并在每个元素上调用execute_phrase。 REPL循环(第427行)在单个Parsetree.toplevel_phrase上调用execute_phrase
7)我仍然不确定究竟是什么导致了解析树的差异 - 但试图弄清楚它是有趣的。
如果了解这些部分的人更多地发布了答案,那将是非常棒的。
答案 1 :(得分:1)
今天我使用utop 1.17和Ocaml 4.02.1遇到了这个问题。在阅读gautamc'e优秀答案后,我尝试了这个简单的解决方法:
utop # type 'a _no_unused_value_warning_ = 'a;;
这使我成功#use使用了我遇到问题的模块。