Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / MLBasisExamples.adoc
CommitLineData
7f918cf1
CE
1MLBasisExamples
2===============
3
4Here are some example uses of <:MLBasis:ML Basis> files.
5
6
7== Complete program ==
8
9Suppose your complete program consists of the files `file1.sml`, ...,
10`filen.sml`, which depend upon libraries `lib1.mlb`, ..., `libm.mlb`.
11
12----
13(* import libraries *)
14lib1.mlb
15...
16libm.mlb
17
18(* program files *)
19file1.sml
20...
21filen.sml
22----
23
24The bases denoted by `lib1.mlb`, ..., `libm.mlb` are merged (bindings
25of names in later bases take precedence over bindings of the same name
26in earlier bases), producing a basis in which `file1.sml`, ...,
27`filen.sml` are elaborated, adding additional bindings to the basis.
28
29
30== Export filter ==
31
32Suppose you only want to export certain structures, signatures, and
33functors from a collection of files.
34
35----
36local
37 file1.sml
38 ...
39 filen.sml
40in
41 (* export filter here *)
42 functor F
43 structure S
44end
45----
46
47While `file1.sml`, ..., `filen.sml` may declare top-level identifiers
48in addition to `F` and `S`, such names are not accessible to programs
49and libraries that import this `.mlb`.
50
51
52== Export filter with renaming ==
53
54Suppose you want an export filter, but want to rename one of the
55modules.
56
57----
58local
59 file1.sml
60 ...
61 filen.sml
62in
63 (* export filter, with renaming, here *)
64 functor F
65 structure S' = S
66end
67----
68
69Note that `functor F` is an abbreviation for `functor F = F`, which
70simply exports an identifier under the same name.
71
72
73== Import filter ==
74
75Suppose you only want to import a functor `F` from one library and a
76structure `S` from another library.
77
78----
79local
80 lib1.mlb
81in
82 (* import filter here *)
83 functor F
84end
85local
86 lib2.mlb
87in
88 (* import filter here *)
89 structure S
90end
91file1.sml
92...
93filen.sml
94----
95
96
97== Import filter with renaming ==
98
99Suppose you want to import a structure `S` from one library and
100another structure `S` from another library.
101
102----
103local
104 lib1.mlb
105in
106 (* import filter, with renaming, here *)
107 structure S1 = S
108end
109local
110 lib2.mlb
111in
112 (* import filter, with renaming, here *)
113 structure S2 = S
114end
115file1.sml
116...
117filen.sml
118----
119
120
121== Full Basis ==
122
123Since the Modules level of SML is the natural means for organizing
124program and library components, MLB files provide convenient syntax
125for renaming Modules level identifiers (in fact, renaming of functor
126identifiers provides a mechanism that is not available in SML).
127However, please note that `.mlb` files elaborate to full bases
128including top-level types and values (including infix status), in
129addition to structures, signatures, and functors. For example,
130suppose you wished to extend the <:BasisLibrary:Basis Library> with an
131`('a, 'b) either` datatype corresponding to a disjoint sum; the type
132and some operations should be available at the top-level;
133additionally, a signature and structure provide the complete
134interface.
135
136We could use the following files.
137
138`either-sigs.sml`
139[source,sml]
140----
141signature EITHER_GLOBAL =
142 sig
143 datatype ('a, 'b) either = Left of 'a | Right of 'b
144 val & : ('a -> 'c) * ('b -> 'c) -> ('a, 'b) either -> 'c
145 val && : ('a -> 'c) * ('b -> 'd) -> ('a, 'b) either -> ('c, 'd) either
146 end
147
148signature EITHER =
149 sig
150 include EITHER_GLOBAL
151 val isLeft : ('a, 'b) either -> bool
152 val isRight : ('a, 'b) either -> bool
153 ...
154 end
155----
156
157`either-strs.sml`
158[source,sml]
159----
160structure Either : EITHER =
161 struct
162 datatype ('a, 'b) either = Left of 'a | Right of 'b
163 fun f & g = fn x =>
164 case x of Left z => f z | Right z => g z
165 fun f && g = (Left o f) & (Right o g)
166 fun isLeft x = ((fn _ => true) & (fn _ => false)) x
167 fun isRight x = (not o isLeft) x
168 ...
169 end
170structure EitherGlobal : EITHER_GLOBAL = Either
171----
172
173`either-infixes.sml`
174[source,sml]
175----
176infixr 3 & &&
177----
178
179`either-open.sml`
180[source,sml]
181----
182open EitherGlobal
183----
184
185`either.mlb`
186----
187either-infixes.sml
188local
189 (* import Basis Library *)
190 $(SML_LIB)/basis/basis.mlb
191 either-sigs.sml
192 either-strs.sml
193in
194 signature EITHER
195 structure Either
196 either-open.sml
197end
198----
199
200A client that imports `either.mlb` will have access to neither
201`EITHER_GLOBAL` nor `EitherGlobal`, but will have access to the type
202`either` and the values `&` and `&&` (with infix status) in the
203top-level environment. Note that `either-infixes.sml` is outside the
204scope of the local, because we want the infixes available in the
205implementation of the library and to clients of the library.