问题
I'm using SML/NJ, and I need to use a set of functions that are in a certain file f1.sml
inside another file f2.sml
.
However, I'm not running f2.sml
directly, rather, I'm importing it from somewhere else.
If I use the use
command in f2.sml
with the path to f1.sml
relative to f2.sml
perspective, by the time I import f2.sml
, it will look for the supplied path from the running script perspective.
I cannot use absolute paths, and I'd like not to merge the two files contents.
Sorry if this is a trivial application of the language, but I'm new to SML, and couldn't find the answer yet.
回答1:
I recommend using SML/NJ's Compilation Manager (CM). It's a build system for SML code in the context of SML/NJ. It can get quite complicated if you need more advanced features, but it's easy to get started. I'll show you a barebones structure and you can adjust as needed. It already comes installed with SML/NJ, so there's no installation process.
I'll use the following directory structure for this example (the file extensions are not imposed, just a convention):
.
├── build.cm
└── src
├── foo.fun
├── foo.sig
└── main.sml
build.cm
group
(* CM allows you to selectively export defined modules (structures,
signatures and functors) by listing them here. It's useful for
libraries. *)
source (-) (* export all defined modules *)
structure Main (* OR, export selectively *)
signature FOO
functor Foo
is
(* Import the SML standard library, aka Basis. *)
(* See: http://sml-family.org/Basis/ *)
$/basis.cm
(* Import the SML/NJ library *)
(* Provides extra data structures and algorithms. *)
(* See: https://www.smlnj.org/doc/smlnj-lib/Manual/toc.html *)
$/smlnj-lib.cm
(* List each source file you want to be considered for compilation. *)
src/main.sml
src/foo.sig
src/foo.fun
src/main.sml
structure Main =
struct
(* You don't have to import the `Foo` functor. *)
(* It's been done in build.cm already. *)
structure F = Foo()
fun main () =
print (F.message ^ "\n")
end
src/foo.sig
signature FOO =
sig
val message : string
end
src/foo.fun
(* You don't have to import the `FOO` signature. *)
(* It's been done in build.cm already. *)
functor Foo() : FOO =
struct
val message = "Hello, World!"
end
Usage
Having the structure in place, you can start compiling using CM.make
and running by calling whatever functions you've defined:
$ sml
Standard ML of New Jersey v110.82 [built: Tue Jan 9 20:54:02 2018]
- CM.make "build.cm";
val it = true : bool
-
- Main.main ();
Hello, World!
val it = () : unit
来源:https://stackoverflow.com/questions/50595106/how-to-import-from-another-file-in-sml-with-a-path-relative-to-the-importer