OCaml模块:包括AND open?

Loï*_*ier 11 ocaml module

我是OCaml模块的新手,我没有设法使用我自己的模块而没有结合"包含"和"打开".我试图将签名放在单独的.mli文件中,但没有成功.

下面我指出了一个最小的(不是)工作示例,我正在尝试编译

ocamlc -o main Robot.ml main.ml
Run Code Online (Sandbox Code Playgroud)

我需要做什么只需要使用"打开",或只使用"包含",但不能同时使用它们?


文件"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
Run Code Online (Sandbox Code Playgroud)

文件"main.ml"(不工作):

open Robot;;

top();
Run Code Online (Sandbox Code Playgroud)

文件"main.ml"(工作):

include Robot;;
open Robot;;

top();
Run Code Online (Sandbox Code Playgroud)

ane*_*eal 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
Run Code Online (Sandbox Code Playgroud)

然后它应该在你的main.ml中有它.

根据以下评论进行更新:如果您担心在打开Robot时现在可以看到robot.ml中的所有内容,您可以定义一个robot.mli文件,该文件指定外部可用的功能.例如,假设您在robot.ml中添加了一个名为helper的函数:

let top () =
  begin
     Printf.printf "top\n"
  end

let helper () =
  Printf.printf "helper\n"
Run Code Online (Sandbox Code Playgroud)

...然后你定义你的robot.mli如下:

val top: unit -> unit
Run Code Online (Sandbox Code Playgroud)

那么假设您尝试从main.ml调用helper:

open Robot;;

top();
(* helper will not be visible here and you'll get a compile error*)
helper ()
Run Code Online (Sandbox Code Playgroud)

然后,当你尝试编译时,你会收到一个错误:

$ ocamlc -o main robot.mli robot.ml main.ml
File "main.ml", line 4, characters 0-6:
Error: Unbound value helper
Run Code Online (Sandbox Code Playgroud)


Tho*_*mas 5

您有两种方法可以做到这一点:

  • 首先,您可以将子结构约束为正确的签名:

    module Robot : RobotSignature = struct ... end
    
    Run Code Online (Sandbox Code Playgroud)

    然后main.ml,你可以这样做open Robot.Robot:第一个Robot意味着与之关联的编译单元robot.ml,第二个Robot是你在里面定义的子模块robot.ml

  • 您还可以删除一个级别并创建robot.mli包含:

    val top: unit -> unit
    
    Run Code Online (Sandbox Code Playgroud)

    robot.ml包含:

    let top () = 
      Printf.printf "top\n"
    
    (* Should not be visible from the 'main' *)
    let dummy () = 
      Printf.printf "dummy\n"
    
    Run Code Online (Sandbox Code Playgroud)

    您可以使用ocamlc -c robot.mli && ocamlc -c robot.ml然后main.ml简单地使用来编译模块open Robot.