我写

let fact x =
let result = ref 1 in
for i = 1 to x do
    result := !result * i;
    Printf.printf "%d %d %d\n" x i !result;
done;
!result;;

在名为“Moduletest.ml”的文件中,以及
val fact : int -> int

在名为“Moduletest.mli”的文件中。

但是,为什么它们不起作用?

当我尝试在ocaml中使用时,
Moduletest.fact 3

它告诉我:
Error: Reference to undefined global `Moduletest'

发生了什么?

谢谢。

最佳答案

OCaml顶层仅与标准库链接。关于如何使其他代码可见,有几种选择:

  • 复制粘贴
  • 从编辑器
  • 进行评估
  • 加载文件#use指令
  • 制作自定义顶级
  • 用ocaml查找
  • 加载

  • 复制粘贴

    这种自我描述,您只需从某些源复制代码,然后将其粘贴到顶层即可。不要忘记,除非添加;;,否则顶层不会评估您的代码

    编辑评价

    编辑器当然是Emacs所在的地方...嗯,的确可以是任何其他有能力的编辑器,例如vim。此方法是对先前方法的详细说明,该方法实际上由编辑器负责为您复制和粘贴代码。在Emacs中,您可以使用C-c C-b命令评估整个文件,也可以使用C-c C-r将其范围缩小到选定区域,最细粒度的是使用C-c C-e,即评估一个表达式。虽然是越野车。

    使用#use指令加载。

    该指令接受文件名,并且实际上将复制并粘贴文件中的代码。请注意,它不会为您创建文件模块/例如,如果您拥有具有以下内容的文件test.ml:
    (* file test.ml *)
    let sum x y = x + y
    

    然后使用#use指令加载它,实际上会将sum值带到您的作用域:
    # #use "test.ml";;
    # let z = sum 2 2
    

    您不必用sum来限定Test.,因为实际上没有创建Test模块。 #use指令仅将文件内容复制到顶层。而已。

    制作自定义顶层

    您可以使用编译的代码来创建自己的顶层。这是一个高级主题,因此我将跳过它。

    ocamlfind加载库
    ocamlfind是一个工具,可让您查找系统上安装的库并将其加载到顶层。默认情况下,除标准库外,顶层不与任何代码链接。甚至不是实际上库的所有部分都已链接在一起,例如Unix模块不可用,需要显式加载。有一些原始指令可以加载任何库,例如#load#include,但它们不适合临时用户使用,尤其是当您拥有出色的ocamlfind时。在使用它之前,您需要加载它,因为默认情况下它也不可用。以下命令将加载ocamlfind并添加一些新指令:
    # #use "topfind";;
    

    在加载过程中,它将向您显示如何使用它的一些提示。添加的最有趣的指令是#require。它接受一个库名,并将其代码加载(即链接)到顶层:
    # #require "unix";;
    

    这将加载一个unix库。如果不确定,请始终使用#list命令查看所有库的名称。 #require指令很聪明,它将自动加载该库的所有依赖项。

    如果您不想在每次启动OCaml顶层时都键入所有这些指令,则可以在主目录中创建.ocamlinit文件,并将其放在此处。该文件将在顶级启动时自动加载。

    10-04 12:54