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'v
t ='v con
val name : 'v con -> string
val make : string ->
('a, 'b) arguments ->
('a -> 'b) -> ('b -> 'a option) -> 'b con
con
using the corresponding field valuesval c0 : string -> 'a -> 'a con
c0 "None" None
val arity : 'a con -> int
C 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 con
val subterms_prod : 'v conap -> Product.dynprod
val subterms : 'v conap -> Ty.dyn list
module Build:sig
..end