1 (* cvs update -r varunion parsing typing bytecomp toplevel *)
3 type t
= private [> ];;
4 type u
= private [> ] ~
[t
];;
6 let f x
= (x
: t
:> v
);;
9 module Mix
(X
: sig type t
= private [> ] end)
10 (Y
: sig type t
= private [> ] end) =
11 struct type t
= [X.t
| Y.t
] end;;
14 module Mix
(X
: sig type t
= private [> `A
of int ] end)
15 (Y
: sig type t
= private [> `A
of bool] ~
[X.t
] end) =
16 struct type t
= [X.t
| Y.t
] end;;
19 module Mix
(X
: sig type t
= private [> `A
of int ] end)
20 (Y
: sig type t
= private [> `A
of int] ~
[X.t
] end) =
21 struct type t
= [X.t
| Y.t
] end;;
24 module Mix
(X
: sig type t
= private [> `A
of int ] end)
25 (Y
: sig type t
= private [> `B
of bool] ~
[X.t
] end) =
26 struct type t
= [X.t
| Y.t
] end;;
28 type 'a t
= private [> `L
of 'a
] ~
[`L
];;
31 module Mix
(X
: sig type t
= private [> `A
of int ] ~
[`B
] end)
32 (Y
: sig type t
= private [> `B
of bool] ~
[X.t
] end) =
33 struct type t
= [X.t
| Y.t
] let is_t = function #t
-> true | _
-> false end;;
35 module Mix
(X
: sig type t
= private [> `A
of int ] ~
[`B
] end)
36 (Y
: sig type t
= private [> `B
of bool] ~
[X.t
] end) =
39 let which = function #
X.t
-> `X
| #
Y.t
-> `Y
42 module Mix
(I
: sig type t
= private [> ] ~
[`A
;`B
] end)
43 (X
: sig type t
= private [> I.t
| `A
of int ] ~
[`B
] end)
44 (Y
: sig type t
= private [> I.t
| `B
of bool] ~
[X.t
] end) =
47 let which = function #
X.t
-> `X
| #
Y.t
-> `Y
52 Mix
(struct type t
= [`C
of char
] end)
53 (struct type t
= [`A
of int | `C
of char
] end)
54 (struct type t
= [`B
of bool | `C
of char
] end);;
58 Mix
(struct type t
= [`B
of bool] end)
59 (struct type t
= [`A
of int | `B
of bool] end)
60 (struct type t
= [`B
of bool | `C
of char
] end);;
63 module M1
= struct type t
= [`A
of int | `C
of char
] end
64 module M2
= struct type t
= [`B
of bool | `C
of char
] end
65 module I
= struct type t
= [`C
of char
] end
66 module M
= Mix
(I
)(M1
)(M2
) ;;
68 let c = (`C '
c'
: M.t
) ;;
70 module M
(X
: sig type t
= private [> `A
] end) =
71 struct let f (#
X.t
as x
) = x
end;;
74 type t
= private [> `A
] ~
[`B
];;
75 match `B
with #t
-> 1 | `B
-> 2;;
77 module M
: sig type t
= private [> `A
of int | `B
] ~
[`C
] end =
78 struct type t
= [`A
of int | `B
| `D
of bool] end;;
79 let f = function (`C
| #
M.t
) -> 1+1 ;;
80 let f = function (`A _
| `B #
M.t
) -> 1+1 ;;
83 module Mix
(X
:sig type t
= private [> ] val show
: t
-> string end)
84 (Y
:sig type t
= private [> ] ~
[X.t
] val show
: t
-> string end) =
87 let show : t
-> string = function
89 | #
Y.t
as y
-> Y.show y
93 type t
= [`Str
of string]
97 type t
= [`Int
of int]
98 let show (`Int i
) = string_of_int i
100 module M
= Mix
(EStr
)(EInt
);;
102 module type T
= sig type t
= private [> ] val show: t
-> string end
103 module Mix
(X
:T
)(Y
:T
with type t
= private [> ] ~
[X.t
]) :
104 T
with type t
= [X.t
| Y.t
] =
108 #
X.t
as x
-> X.show x
109 | #
Y.t
as y
-> Y.show y
111 module M
= Mix
(EStr
)(EInt
);;
114 module M
: sig type t
= private [> `A
] end = struct type t
= [`A
] end
115 module M'
: sig type t
= private [> ] end = struct type t
= [M.t
| `A
] end;;
118 type t
= private [> ]
119 type u
= private [> `A
of int] ~
[t
] ;;
122 type t
= private [> `A
of int]
123 type u
= private [> `A
of int] ~
[t
] ;;
126 type t
= private [> ] ~
[`A
;`B
;`C
;`D
]
127 type u
= private [> `A
|`B
|`C
] ~
[t
; `D
]
128 end) : sig type v
= private [< X.t
| X.u
| `D
] end = struct
130 let f = function #u
-> 1 | #t
-> 2 | `D
-> 3
131 let g = function #u
|#t
|`D
-> 2
136 module M
= struct type t
= private [> `A
] end;;
137 module M'
: sig type t
= private [> ] ~
[`A
] end = M
;;
140 module type T
= sig type t
= private [> ] ~
[`A
] end;;
141 module type T'
= T
with type t
= private [> `A
];;
144 type t
= private [> ] ~
[`A
]
145 let f = function `A x
-> x
| #t
-> 0
146 type t'
= private [< `A
of int | t
];;
149 module F
(X
:sig end) :
150 sig type t
= private [> ] type u
= private [> ] ~
[t
] end =
151 struct type t
= [ `A
] type u
= [`B
] end
153 let f = function #
M.t
-> 1 | #
M.u
-> 2
154 let f = function #
M.t
-> 1 | _
-> 2
156 let f = function #t
-> 1 | _
-> 2;;
157 module G
(X
: sig type t
= private [> ] type u
= private [> ] ~
[t
] end) =
158 struct let f = function #
X.t
-> 1 | _
-> 2 end;;
159 module M1
= G
(struct module N
= F
(String
) type t
= N.t
type u
= N.u
end) ;;
160 module M1
= G
(struct type t
= M.t
type u
= M.u
end) ;;
162 let f = function #F
(String
).t
-> 1 | _
-> 2;;
163 type t
= [F
(String
).t
| M.u
]
164 let f = function #t
-> 1 | _
-> 2;;
165 module N
: sig type t
= private [> ] end =
166 struct type t
= [F
(String
).t
| M.u
] end;;
168 (* compatibility improvement *)
169 type a
= [`A
of int | `B
]
170 type b
= [`A
of bool | `B
]
171 type c = private [> ] ~
[a
;b
]
172 let f = function #
c -> 1 | `A x
-> truncate x
173 type d
= private [> ] ~
[a
]
174 let g = function #d
-> 1 | `A x
-> truncate x
;;
177 (* Expression Problem: functorial form *)
179 type num
= [ `Num
of int ]
181 module type Exp
= sig
182 type t
= private [> num
]
184 val show : t
-> string
187 module Num
(X
: Exp
) = struct
189 let eval (`Num _
as x
) : X.t
= x
190 let show (`Num n
) = string_of_int n
193 type 'a add
= [ `Add
of 'a
* 'a
]
195 module Add
(X
: Exp
with type t
= private [> num
| 'a add
] as 'a
) = struct
197 let show (`Add
(e1
, e2
) : t
) = "("^
X.show e1 ^
"+"^
X.show e2 ^
")"
198 let eval (`Add
(e1
, e2
) : t
) =
199 let e1 = X.eval e1 and e2
= X.eval e2
in
201 `Num n1
, `Num n2
-> `Num
(n1
+n2
)
202 | `Num
0, e
| e
, `Num
0 -> e
206 type 'a mul
= [`Mul
of 'a
* 'a
]
208 module Mul
(X
: Exp
with type t
= private [> num
| 'a mul
] as 'a
) = struct
210 let show (`Mul
(e1, e2
) : t
) = "("^
X.show e1 ^
"*"^
X.show e2 ^
")"
211 let eval (`Mul
(e1, e2
) : t
) =
212 let e1 = X.eval e1 and e2
= X.eval e2
in
214 `Num n1
, `Num n2
-> `Num
(n1
*n2
)
215 | `Num
0, e
| e
, `Num
0 -> `Num
0
216 | `Num
1, e
| e
, `Num
1 -> e
220 module Ext
(X
: sig type t
= private [> ] end)(Y
: sig type t
end) = struct
223 type t
= private [> ] ~
[ X.t
]
225 val show : t
-> string
229 module Dummy
= struct type t
= [`Dummy
] end
231 module Mix
(E
: Exp
)(E1
: Ext
(Dummy
)(E
).S
)(E2
: Ext
(E1
)(E
).S
) =
233 type t
= [E1.t
| E2.t
]
235 #
E1.t
as x
-> E1.eval x
236 | #
E2.t
as x
-> E2.eval x
238 #
E1.t
as x
-> E1.show x
239 | #
E2.t
as x
-> E2.show x
242 module rec EAdd
: (Exp
with type t
= [num
| EAdd.t add
]) =
243 Mix
(EAdd
)(Num
(EAdd
))(Add
(EAdd
))
245 (* A bit heavy: one must pass E to everybody *)
246 module rec E
: Exp
with type t
= [num
| E.t add
| E.t mul
] =
247 Mix
(E
)(Mix
(E
)(Num
(E
))(Add
(E
)))(Mul
(E
))
249 let e = E.eval (`Add
(`Mul
(`Num
2,`Num
3),`Num
1))
252 (* Direct approach, no need of Mix *)
253 module rec E
: (Exp
with type t
= [num
| E.t add
| E.t mul
]) =
260 | #num
as x
-> E1.show x
261 | #add
as x
-> E2.show x
262 | #mul
as x
-> E3.show x
264 | #num
as x
-> E1.eval x
265 | #add
as x
-> E2.eval x
266 | #mul
as x
-> E3.eval x
269 (* Do functor applications in Mix *)
270 module type T
= sig type t
= private [> ] end
271 module type Tnum
= sig type t
= private [> num
] end
273 module Ext
(E
: Tnum
) = struct
274 module type S
= functor (Y
: Exp
with type t
= E.t
) ->
276 type t
= private [> num
]
278 val show : t
-> string
282 module Ext'
(E
: Tnum
)(X
: T
) = struct
283 module type S
= functor (Y
: Exp
with type t
= E.t
) ->
285 type t
= private [> ] ~
[ X.t
]
287 val show : t
-> string
291 module Mix
(E
: Exp
)(F1
: Ext
(E
).S
)(F2
: Ext'
(E
)(F1
(E
)).S
) =
295 type t
= [E1.t
| E2.t
]
297 #
E1.t
as x
-> E1.eval x
298 | #
E2.t
as x
-> E2.eval x
300 #
E1.t
as x
-> E1.show x
301 | #
E2.t
as x
-> E2.show x
304 module Join
(E
: Exp
)(F1
: Ext
(E
).S
)(F2
: Ext'
(E
)(F1
(E
)).S
)
305 (E'
: Exp
with type t
= E.t
) =
308 module rec EAdd
: (Exp
with type t
= [num
| EAdd.t add
]) =
311 module rec EMul
: (Exp
with type t
= [num
| EMul.t mul
]) =
314 module rec E
: (Exp
with type t
= [num
| E.t add
| E.t mul
]) =
315 Mix
(E
)(Join
(E
)(Num
)(Add
))(Mul
)
317 (* Linear extension by the end: not so nice *)
318 module LExt
(X
: T
) = struct
323 val show : t
-> string
326 module LNum
(E
: Exp
)(X
: LExt
(E
).S
with type t
= private [> ] ~
[num
]) =
330 `Num n
-> string_of_int n
331 | #
X.t
as x
-> X.show x
334 | #
X.t
as x
-> X.eval x
336 module LAdd
(E
: Exp
with type t
= private [> num
| 'a add
] as 'a
)
337 (X
: LExt
(E
).S
with type t
= private [> ] ~
[add
]) =
339 type t
= [E.t add
| X.t
]
341 `Add
(e1,e2
) -> "("^
E.show e1 ^
"+"^
E.show e2 ^
")"
342 | #
X.t
as x
-> X.show x
345 let e1 = E.eval e1 and e2
= E.eval e2
in
346 begin match e1, e2
with
347 `Num n1
, `Num n2
-> `Num
(n1
+n2
)
348 | `Num
0, e | e, `Num
0 -> e
351 | #
X.t
as x
-> X.eval x
356 let eval `Dummy
= `Dummy
358 module rec L
: Exp
with type t
= [num
| L.t add
| `Dummy
] =
359 LAdd
(L
)(LNum
(L
)(LEnd
))
361 (* Back to first form, but add map *)
363 module Num
(X
: Exp
) = struct
366 let eval1 (`Num _
as x
) : X.t
= x
367 let show (`Num n
) = string_of_int n
370 module Add
(X
: Exp
with type t
= private [> num
| 'a add
] as 'a
) = struct
372 let show (`Add
(e1, e2
) : t
) = "("^
X.show e1 ^
"+"^
X.show e2 ^
")"
373 let map f (`Add
(e1, e2
) : t
) = `Add
(f e1, f e2
)
374 let eval1 (`Add
(e1, e2
) as e : t
) =
376 `Num n1
, `Num n2
-> `Num
(n1
+n2
)
377 | `Num
0, e | e, `Num
0 -> e
381 module Mul
(X
: Exp
with type t
= private [> num
| 'a mul
] as 'a
) = struct
383 let show (`Mul
(e1, e2
) : t
) = "("^
X.show e1 ^
"*"^
X.show e2 ^
")"
384 let map f (`Mul
(e1, e2
) : t
) = `Mul
(f e1, f e2
)
385 let eval1 (`Mul
(e1, e2
) as e : t
) =
387 `Num n1
, `Num n2
-> `Num
(n1
*n2
)
388 | `Num
0, e | e, `Num
0 -> `Num
0
389 | `Num
1, e | e, `Num
1 -> e
393 module Ext
(X
: sig type t
= private [> ] end)(Y
: sig type t
end) = struct
396 type t
= private [> ] ~
[ X.t
]
397 val map : (Y.t
-> Y.t
) -> t
-> t
399 val show : t
-> string
403 module Mix
(E
: Exp
)(E1
: Ext
(Dummy
)(E
).S
)(E2
: Ext
(E1
)(E
).S
) =
405 type t
= [E1.t
| E2.t
]
407 #
E1.t
as x
-> (E1.map f x
: E1.t
:> t
)
408 | #
E2.t
as x
-> (E2.map f x
: E2.t
:> t
)
410 #
E1.t
as x
-> E1.eval1 x
411 | #
E2.t
as x
-> E2.eval1 x
413 #
E1.t
as x
-> E1.show x
414 | #
E2.t
as x
-> E2.show x
419 val map : (t
-> t
) -> t
-> t
421 val show : t
-> string
424 module Fin
(E
: ET
) = struct
426 let rec eval e = eval1 (map eval e)
429 module rec EAdd
: (Exp
with type t
= [num
| EAdd.t add
]) =
430 Fin
(Mix
(EAdd
)(Num
(EAdd
))(Add
(EAdd
)))
432 module rec E
: Exp
with type t
= [num
| E.t add
| E.t mul
] =
433 Fin
(Mix
(E
)(Mix
(E
)(Num
(E
))(Add
(E
)))(Mul
(E
)))
435 let e = E.eval (`Add
(`Mul
(`Num
2,`Num
3),`Num
1))