module Con:sig..end
type ('a, 'v) arguments =
| |
Product of |
| |
Record of |
type ('t, 'v) desc = {
|
name : |
(* |
name of the constructor
| *) |
|
args : |
(* |
arguments of the constructor
| *) |
|
embed : |
(* |
applies the constructor to the arguments.
| *) |
|
proj : |
(* |
tries to deconstruct that constructor
| *) |
('t, 'v) desc describes one of the constructors of variant 'v of type 't.
't is a product type witnessed by the field args.embed is used to build a value of the
variant type corresponding to the constructor.proj tries to deconstruct the variant
value using that constructor, if it succeeds, the
arguments are returned.
A constructor C of (a * b) is treated differently as
constructor C of a * b.
We must therefore represent them differently:
the first one with : { args = Product.p1 (Pair a b) ; ...}
and the second one with: { args = Product.p2 a b ; ...}
Caution!
embed must not inspect its arguments either by
pattern matching on them or by applying a function on
them. embed should only apply the data constructor
to its argument, for instance the embed function for
the data-constructor Some : 'a -> 'a option is embed
= fun x -> Some x.
val product : ('t, 'v) desc -> 't Product.t
type 'v con =
| |
Con : |
't of the constructor arguments is hidden by existential quantification.type'vt ='v con
val name : 'v con -> string
val make : string ->
('a, 'b) arguments ->
('a -> 'b) -> ('b -> 'a option) -> 'b concon using the corresponding field valuesval c0 : string -> 'a -> 'a conc0 "None" Noneval arity : 'a con -> intC of int * bool has arity 2 whereas
C of (int * bool) has arity 1: a single argument which is a pair.type 'v conap =
| |
Conap : |
val conap : 'v con -> 'v -> 'v conap option
val con : 'v conap -> 'v conval subterms_prod : 'v conap -> Product.dynprodval subterms : 'v conap -> Ty.dyn listmodule Build:sig..end