I wrote
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;;
in a file named "Moduletest.ml", and
val fact : int -> int
in a file named "Moduletest.mli".
But, why don't they work?
When I tried to use in ocaml,
Moduletest.fact 3
it told me:
Error: Reference to undefined global `Moduletest'
What's happening?
Thanks.
OCaml toplevel is linked only with a standard library. There're several options on how to make other code visible to it:
#use
directive This self-describing, you just copy code from some source and paste it into toplevel. Don't forget that toplevel won't evaluate your code until you add ;;
Where the editor is of course Emacs... Well, indeed it can be any other capable editor, like vim for example. This method is an elaboration of the previous, where the editor is actually responsible for copying and pasting the code for you. In Emacs you can evaluate the whole file with C-c C-b
command, or you can narrow it to a selected area with C-c C-r
, and the most granular is to use C-c C-e
, i.e., evaluate an expression. Although it is slightly buggy.
#use
directive.This directive accepts a filename, and it will essentially copy and paste the code from the file. Notice, that it won't create a file-module for you/ For example, if you have file test.ml
with this contents:
(* file test.ml *)
let sum x y = x + y
then loading it with the #use
directive, will actually bring to your scope, sum
value:
# #use "test.ml";;
# let z = sum 2 2
You mustn't to qualify sum
with Test.
, because no Test
module is actually created. #use
directive merely copies the contents of the file to the toplevel. Nothing more.
You can create your own toplevel with your code compiled in. It is an advanced theme, so I will skip it.
ocamlfind
ocamlfind
is a tool that allows you to find and load libraries, installed on your system, into your toplevel. By default, toplevel is not linked with any code except standard library. Even, not all parts of the library are actually linked, e.g., Unix
module is not available, and needed to be loaded explicitly. There're primitive directives that can load any library, like #load
and #include
, but they are not for a casual user, especially if you have excellent ocamlfind
at your disposal. Before using it, you need to load it, since it is also not available by default. The following command, will load ocamlfind
and add few new directives:
# #use "topfind";;
In a process of loading it will show you a little hint on how to use it. The most interesting directive, that is added is #require
. It accepts a library name, and loads (i.e., links) its code into toplevel:
# #require "unix";;
This will load a unix
library. If you're not sure, about the name of the library you can always view all libraries with a #list
command. The #require
directive is clever and it will automatically load all dependencies of the library.
If you do not want to type all this directives every time you start OCaml top-level, then you cam create .ocamlinit
file in your home directory, and put them there. This file will be loaded automatically on a top-level startup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With