I'm reading an OCaml project recently and I want to put the source files in the utop so I can do some experiments.
Suppose I have two files amodule.ml, bmodule.ml.
bmodule.ml will use functions defined in amodule.ml, for example, bmodule use Amodule.anyfunction() where anyfunction() is defined in amodule.ml.
I want to put both of them in utop:
#directory "/directory contain amodule.ml and bmodule.ml"
#use "amodule.ml"
#use "bmodule.ml"
And this doesn't work because Amodule is a module name base on the amodule.ml file and the utop don't know these things, I think.
So how I can put these files in the utop without changing the file content?
#use a.ml executes every statement in a.ml just as if you had typed those statements in the toplevel directly. Thus, you do not get a module A defined, so your other file cannot have things like A.foo. If you want module A, you must first byte compile a.ml, and then #load a.cmo.
Related
I have just started to learn Ocaml.
I'm using visual code as my IDE on Ubuntu,
and I have OCaml extension and merlin installed.
and I have the following problem -
my workspace folder contains only 2 files:
a.ml and b.ml.
In the file a.ml I have defined a module named "COOL", and in the file b.ml I wrote:
~ b.ml ~
open COOL;;
I get an error that says "Unbound module COOL merlin"
Is there any way to make it see the module on file a.ml?
I tried searching for solution, I saw something with makefile and .merlin and B build
but I didn't understand it, I don't have anything but the 2 files I mentioned.
I would be happy if someone can tell me what exactly should be done in order for this little example to work.
tl; dr: do ocamlc -c a.ml (or whatever your compilation command is) in order to generate the a.cmi file that merlin will use to get the list of symbols defined in module A.
Apart the fact that in b.ml your module is indeed named A.COOL (unless you open A before open COOL) as mentioned by glennsl, the point is that merlin is, as far as I know, only watching the current file being edited, i.e. b.ml in your case. In order to have access to external symbols, you thus need to have compiled the other files (or at least their corresponding .mli if they exist), in order to have the relevant .cmi files available to merlin.
This is implicit in the paragraph of the documentation describing build paths, which says "[merlin] needs to know where to find the cmi files of the other modules of your project", i.e. those files need to exist in the first place.
The Ocaml manual contains an exercise (here) in which library object files are loaded in the toplevel loop (the ocaml interactive interpreter) in the following way:
#load "dynlink.cma";;
#load "camlp4o.cma";;
I'm trying to replicate the subsequent code in a compilable source file, and the code requires the above library object files. Can I load these files with a line of code within the source file and compile it with ocamlc? I've tried "#load", "load", "#use", "use", "#require", "require", and all these proceded by "#directory" and "directory". I know that you can include modules with "include ;;", but this shouldn't work either, because they're just library files, not modules. I've tried to find a way to do this in the manual, but to no avail.
Do I need to reference the files in the compilation command? If so, how do I do this?
Directives starting with a # character are used only in the toplevel and are not strictly part of the OCaml language. In a file that you want to compile, you don't use # directives. See the OCaml manual Chapter 9. The #load directives are for loading a library. When compiling a file, you have to tell the compiler to use the library (on the command line, not in the file). It's good to learn the compiler commands directly at first, but eventually you should use ocamlfind and oasis, which make compilation much easier.
I'm assuming your source is written using extensions implemented by camlp4o. To compile your source, you can say:
ocamlc -pp camlp4o -o myfile myfile.ml
I believe the complexities of the #load command are required only when you want to use the extensions in the toplevel (the interpreter).
I would like to give two .ml sources files the same name in different directories in my source tree, but the OCaml documentation states that the a file A.ml is exported as a toplevel module A = struct ... end. If I have two files X/A.ml and Y/A.ml, how can I refer to them both from B.ml?
Modules can contain modules, i.e. you can have a hierarchy of modules.
From the B.ml point of view, you can see two modules named X.A and Y.A .
They can even both have a function named foo, those functions would be seen as X.A.foo and Y.A.foo .
Beware that if you open both modules X and Y, the module A from Y will hide the module A from X.
That was from the namespace point of view. Now, about the source tree.
One way would be to have those files:
x.ml
X/a.ml
y.ml
y/a.ml
The file x.ml is automatically generated and contains just this:
module A = struct
(*The contents of x/a.ml is included here*)
end
Likewise for y.ml
There are several preprocessors able to include a file: cpp, camlp4, camlp5, camlmix...
This set of automatically generated files (and regenerated each time the source changes) is not very satisfiying, I will look at other answers.
You can also have a look at ocamlc -pack, but when I tried it a long time ago there was a problem with ocamldoc unable to have x/a.ml and y/a.ml . So check this before you settle on a tool.
You cannot link modules with the same name into the same program. For example, extensions to the standard library, such as Batteries and Core, are forced to give standard modules a different name. In Batteries, the List module is called BatList. Then, they provide a wrapper module Batteries, within which the module is renamed with by doing module List = BatList. The overall path to this module is Batteries.List, so there is no clash with the Standard Library's top level List. Finally, the recommended way of using Batteries and Core is to do open Batteries and open Core, thereby giving you access to their additional list functions under the module name List.
Thus the only option is to rename your modules, but you can do this in two ways:
Change the base names of the modules, e.g. call them A and B.
Put the modules under another module, e.g. name them X.A and Y.A. If you want to keep your current directory structure, you can use OCaml's -pack option. Personally, I find this option too restrictive and always end up doing manual packing, i.e. the technique described above used by Batteries and Core.
Say I have an OCaml library file foo.cma. Is there a command line tool to print the signature of the functions and other types defined there ? The ocamlbrowser utility seems to be windows-based (complains about the $DISPLAY environment variable). The use case is that I am doing a:
ocamlc -c foo.cma main.ml
and get:
File "main.ml", line 13, characters 33-47:
Error: Unbound value ListUtil.split
ListUtil.split ought to reside in foo.cma but I don't know a console-based tool to verify it.
On Debian/Ubuntu, you have "ocamlobjinfo":
ocamlobjinfo stdlib.cma
will display all the unit names included in stdlib.cma. Then, you can create a short file:
include SomeModule
and compile it with -i to see what is defined in module SomeModule.
In the toplevel, I just load the cma file:
#load "foo.cma";;
Then I re-defined a module just to see the signature:
module Chunk = Foo;;
In order to compile the code referencing ListUtil.split the compiler needs to find the corresponding listUtil.cmi file. In order to link that code compiler will need the cma (or cmo) file containing the implementation. See http://mirror.ocamlcore.org/caml.inria.fr/pub/ml-archives/caml-list/2008/09/2bc9b38171177af5dc0d832a365d290d.en.html for some explanation.
in file testmodule.ml
module TestModule =
struct
type my_type = MyType1 | MyType2
end
How can I use TestModule in top-level?
after "ocamlc -c testmodule.ml" (this generated testmodule.cmo/cmi)
I tried "open TestModule", but error "unbound module TestModule" occured.
Objective Caml version 3.10.0
# open TestModule;;
Unbound module TestModule
then, I tried making top-level with that module. but...
indi#www:~/std/toq$ ocamlmktop -o mytop testmodule.ml
indi#www:~/std/toq$ ./mytop
Objective Caml version 3.10.0
# TestModule.MyType1;;
Unbound constructor TestModule.MyType1
# open TestModule;;
Unbound module TestModule
What can I do for using my TestModule???
The directives you can use in the toplevel to that effect are listed in the manual.
You can try #use "testmodule.ml";;, or, alternatively #load "testmodule.cmo";; after having compiled your module.
As huitseeker mentioned, you can use #use "testmodule.ml";;. However, this will make the module Testmodule avialable, and your TestModule module is actually Testmodule.TestModule. .cmo files (generated from .ml files) define a module whose name is that of the CMO with the first letter capitalized. Therefore, I would omit the module TestModule ... part of your code, and simply put your code in a file called testModule.ml. You can then compile it and use #use "testModule.ml";; to access the module.
Tu summarize: a few minor details all conspired together against you :-)
First, as mentioned previously, you need to load the code into the toplevel with either #use "testmodule.ml";; for source files or #load "testmodule.cmo";; for compiled files, or to use ocamlmktop. This explains why your first attempt did not work: you did not load the code.
Second, you defined module TestModule in a file called testmodule.ml. Keep in mind that the file defines its own module based on its name. So, in order to access your module, you need to write Testmodule.TestModule. This explains why your second attempt did not work: the code was loaded but had an unexpected name.
You might wish to remove the TestModule definition and rename the file to testModule.ml (or the perhaps more idiomatic test_module.ml).