我对OCaml模块相当新,我没有设法使用我自己的模块而没有结合“包含”和“打开”。 我试图将签名放在一个单独的.mli文件中,但没有成功。
下面我指出了一个最小(非)工作示例,我正在尝试使用
进行编译ocamlc -o main Robot.ml main.ml
我需要做什么才能使用“开放”或仅使用“包含”,而不是两者都使用?
文件“Robot.ml”:
module type RobotSignature =
sig
val top: unit -> unit
end
module Robot =
struct
let top () =
begin
Printf.printf "top\n"
end
(* Should not be visible from the 'main' *)
let dummy () =
begin
Printf.printf "dummy\n"
end
end
文件“main.ml”(不工作):
open Robot;;
top();
文件“main.ml”(正在工作):
include Robot;;
open Robot;;
top();
答案 0 :(得分:12)
你有两个级别的机器人。由于您在文件robot.ml中明确调用了模块“Robot”,因此您需要打开Robot然后调用Robot.top()。 robot.ml文件中的任何内容都已隐式放在Robot模块中。
你可以摆脱robot.ml中额外的'模块机器人'声明。
robot.ml将成为:
module type RobotSignature =
sig
val top: unit -> unit
end
let top () =
begin
Printf.printf "top\n"
end
然后它应该在你的main.ml中有效。
根据以下评论进行更新:如果您担心在打开Robot时现在可以看到robot.ml中的所有内容,您可以定义一个robot.mli文件,该文件指定了可在外部使用。例如,假设您在robot.ml中添加了一个名为 helper 的函数:
let top () =
begin
Printf.printf "top\n"
end
let helper () =
Printf.printf "helper\n"
...然后按如下方式定义你的robot.mli:
val top: unit -> unit
然后假设您尝试从main.ml中调用helper:
open Robot;;
top();
(* helper will not be visible here and you'll get a compile error*)
helper ()
然后当你尝试编译时,你会收到一个错误:
$ ocamlc -o main robot.mli robot.ml main.ml
File "main.ml", line 4, characters 0-6:
Error: Unbound value helper
答案 1 :(得分:5)
您有两种方法可以做到这一点:
首先,您可以将子结构约束为正确的签名:
module Robot : RobotSignature = struct ... end
然后在main.ml
中,您可以执行open Robot.Robot
:第一个Robot
表示与robot.ml
关联的编译单元,第二个Robot
表示您的子模块在robot.ml
您还可以删除一个级别并创建包含以下内容的robot.mli
:
val top: unit -> unit
和robot.ml
包含:
let top () =
Printf.printf "top\n"
(* Should not be visible from the 'main' *)
let dummy () =
Printf.printf "dummy\n"
您可以使用ocamlc -c robot.mli && ocamlc -c robot.ml
编译模块,然后在main.ml
中使用open Robot
。