module Generic_core_extensible:sig..end
Type-indexed functions are ad-hoc polymorphic functions rather than parametric polymorphic: their behaviour may change depending on the type.
We implement them in Ocaml using a type 'a ty (see Generic_core_ty.ty) whose
constructors reflect the type parameter:
Int : int ty
List : 'a ty -> 'a list ty
The type ty is extensible to allow users to add their own types.
Therefore when defining functions on ty we need to be able
to extend them as we extend ty. This is the purpose of this
module.
The general type of type-indexed function is given by
type 'f ty_fun = { f : 'a . 'a ty -> ('a,'f) app }
where we used a defunctionalisation method to deal with
parameterised types, see Generic_util_app. The
idea is that ('a, 'f) app represents the application of a
type 'f to a type parameter 'a.
An extensible function is a collection of such ty_fun.
A collection is created with function create whose result is a closure
of type 'b extensible_closure whose field f is the extensible function,
and field ext allows to extend it to a new case by providing
a type pattern and a ty_fun matching that type pattern.
Calling the extensible function with the field f will raise
a Type_pattern_match_failure exception when the type index
doesn't match any of the patterns in the collection.
Extending an extensible function with the field ext will
raise a Type_pattern_overwrite exception when called with
a type pattern that was already registered.
exception Type_pattern_match_failure of string
f field of a Generic_core_extensible.closure when there is no
case registered to deal with the type witness.exception Type_pattern_overwrite of string
ext field of a Generic_core_extensible.closure when trying to extend a type indexed function
with a case for a pattern that is already covered.type 'b ty_fun = {
|
f : |
'b is the code for a parametric type 'a f
such that 'b ty_fun is equivalent to for all 'a . 'a ftype 'b closure = {
|
f : |
(* | f: applies the extensible function.Raises Type_pattern_match_failure when the type index doesn't
match any of the patterns in the collection. | *) |
|
ext : |
(* | ext: extends the function with a new case. We must
provide a type pattern, (example: List Any). The
ty_fun provided is only expected to handle types
matching with the pattern. Effectful.Raises Pattern_overwrite when called with a type pattern that
was already registered. | *) |
val create : string -> 'f closurecreate name, creates a new closure initially empty:
calling f will raise
Type_pattern_match_failure. The name is used in the exception messages. Effectful.