Functional programming 为什么;引用未定义的全局“Moduletest'&引用;用OCaml?
我写Functional programming 为什么;引用未定义的全局“Moduletest'&引用;用OCaml?,functional-programming,ocaml,Functional Programming,Ocaml,我写 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”的文件中 在名为“Moduletest.mli”的文件中 但是,他们为什么不工作呢 当我尝试在ocaml中使用时 Moduletest.fact 3 它告诉我: Error
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”的文件中
在名为“Moduletest.mli”的文件中
但是,他们为什么不工作呢
当我尝试在ocaml中使用时
Moduletest.fact 3
它告诉我:
Error: Reference to undefined global `Moduletest'
发生了什么事
谢谢。我已经测试了你的代码,看起来不错。您应该通过以下方式从OCaml顶层“加载”它(从与
.ml
和.mli
文件相同的目录启动):
# #use "Moduletest.ml";;
val fact : int -> int = <fun>
# fact 4;;
4 1 1
4 2 2
4 3 6
4 4 24
- : int = 24
##使用“Moduletest.ml”;;
val事实:int->int=
#事实4;;
4 1 1
4 2 2
4 3 6
4 4 24
-:int=24
OCaml toplevel仅与标准库链接。关于如何使其他代码对其可见,有几个选项:
#使用
指令;之前,toplevel不会对代码求值代码>
编辑的评价
编辑当然是Emacs。。。实际上,它可以是任何其他有能力的编辑器,比如vim。此方法是前一种方法的精化,编辑器实际上负责为您复制和粘贴代码。在Emacs中,您可以使用C-C-b
命令对整个文件求值,也可以使用C-C-r
将其缩小到选定区域,最精确的方法是使用C-C-e
,即对表达式求值。虽然它有点车
使用指令加载。
这个指令接受一个文件名,它将从文件中复制并粘贴代码。请注意,它不会为您创建文件模块/例如,如果您有包含以下内容的文件test.ml
:
(* file test.ml *)
let sum x y = x + y
然后用#use
指令加载它,实际上会将sum
值带入您的范围:
# #use "test.ml";;
# let z = sum 2 2
您不能使用Test.
来限定sum
,因为实际上没有创建Test
模块#use
指令仅将文件内容复制到顶层。没别的了
制作定制顶层
您可以使用中编译的代码创建自己的顶级。这是一个高级主题,所以我将跳过它
使用ocamlfind
ocamlfind
是一种工具,允许您查找安装在系统上的库并将其加载到顶级中。默认情况下,toplevel不与标准库以外的任何代码链接。甚至,并非库的所有部分都实际链接,例如,Unix
模块不可用,需要显式加载。有一些基本指令可以加载任何库,如#load
和#include
,但它们不适合临时用户,特别是当您拥有优秀的ocamlfind
可供使用时。在使用它之前,您需要加载它,因为默认情况下它也不可用。以下命令将加载ocamlfind
,并添加一些新指令:
# #use "topfind";;
在加载过程中,它将向您展示如何使用它的一些提示。添加的最有趣的指令是#require
。它接受库名称,并将其代码加载(即链接)到顶级:
# #require "unix";;
这将加载一个unix
库。如果您不确定库的名称,则始终可以使用#list
命令查看所有库。#require
指令很聪明,它将自动加载库的所有依赖项
如果您不想在每次启动OCaml顶级时都键入所有这些指令,那么您可以在主目录中创建.ocamlinit
文件,并将它们放在那里。此文件将在顶级启动时自动加载。您是如何“在ocaml中使用”的?使用#使用
或#加载
或从其他文件加载?你是怎么编译的?您的代码似乎没有任何问题。我假设您使用的是#use
,这只是将文件的内容输入顶层,因此没有周围的隐式模块名(按文件)。我的教授告诉我应该在cmd或terminal:ocaml moduletest.cmo中编译和编写。最后,我发现它可以工作。是的,除了交互式顶层,OCaml还有一个编译器=)
# #require "unix";;