定义一个模块并在一个文件中调用它的功能

时间:2012-01-16 16:56:13

标签: module ocaml

我在文件mod.ml中定义了一个模块,如下所示:

module Area = struct
  ...
  let test : unit =
    Print.printf "haha"
  ...
end;;

Print.printf "hehe";;

Area.test

似乎在;;之后没有end,我无法按ocamlc编译代码。但是我在Ocaml文件中使用;;看起来很奇怪,我是否必须保留它们?

mod生成ocamlc后,我启动mod,打印hahahehe。似乎hahalet test : unit ...的定义打印,而不是其Area.test。我的结果是hehehahahahahehehaha。谁能解释为什么它不是我的预期呢?

2 个答案:

答案 0 :(得分:4)

我从未在源文件中使用;;,我认为它是顶级界面的一部分。对于你的代码,我可能会写:

module Area = struct
  let test : unit -> unit =
      fun () -> Printf.printf "haha"
end

let () =
    Printf.printf "hehe";
    Area.test ()

对于它的价值,Area.test如你所定义的那样它不是一个函数,它只是一个在计算过程中带有副作用的单位值。在我的代码中,我已将其更改为unit -> unit类型的函数。

答案 1 :(得分:4)

ocamlc加载模块时,它会按照定义的顺序评估所有“顶层”定义。在您的情况下,您有三个“顶级”定义。

  • 第一个是值unit(类型unit的唯一值),它绑定到名称“test”。副作用后生成此值:显示“haha”(此处模块Area用作命名空间,不会延迟计算);

  • seconde one也是值unit,但没有名字绑定;此值也会产生副作用:显示“hehe”;

  • 最后一个只是与名称“test”相关联的值,即。 unit。但是,这次没有副作用,因为已经生成了与名称“test”相关联的值unit

如果您希望每次调用test时都有副作用,则需要使用函数:

let test () =  Print.printf "haha"

对于问题的;;部分。解析器需要这些来知道表达式何时结束。还有其他方法可以帮助解析器,例如:

let () = Print.printf "hehe"

或者简单地说:

let _ = Area.test

最新版本更短,因为您不必指出类型信息,但更容易出错,因为编译器在部分应用时不会让您感到温暖。