module Generic_core_ty:sig
..end
The type _ ty
reflects type terms as value terms.
We call such terms /type codes/.
The GADT syntax allows us to constrain the type parameter of _ ty
so that for any given
type t
, there is at most one value of type t ty
, that value is the reflection of t
.
For each type of arity n
, corresponds a ty
constructor of arity n
whose arguments are themselves
ty
values reflecting the type parameters.
_ ty
is extensible: when the user defines a new type ('a0,...'an) t
,
we add a homonymous constructor to _ty
:
_ ty += T : 'a0 ty * ... * 'an ty -> ('a0,...'an) t ty
module T:sig
..end
type'a
t ='a T.ty
type'a
ty ='a T.ty
= ..
type '_
ty +=
| |
Any : |
| |
Int32 : |
| |
Int64 : |
| |
Nativeint : |
| |
Lazy : |
| |
Exn : |
| |
Bool : |
| |
Int : |
| |
Float : |
| |
Char : |
| |
Bytes : |
| |
String : |
| |
Option : |
| |
List : |
| |
Array : |
| |
Ref : |
| |
Ty : |
| |
Unit : |
| |
Pair : |
| |
Triple : |
| |
Quadruple : |
| |
Quintuple : |
| |
Sextuple : |
| |
Septuple : |
| |
Octuple : |
| |
Nonuple : |
| |
Decuple : |
| |
Fun : |
ty'
is the union of all 'a ty
for all 'a
.type
ty' =
| |
E : |
ty'
we may now compare 'a ty
and 'b ty
values
using the generic equality primitive.val eq : 'a ty -> 'b ty -> bool
val neq : 'a ty -> 'b ty -> bool
val with_type : 'a ty -> 'a -> 'a
with_type
is used to help the type-checker fix the type of a value to the index of ='a ty=.
The type synonym 'a pat
is meant to mark the contexts
where patterns are expected rather than type codes. Any type code
is also a type pattern, but in addition there is a wildcard
pattern Generic_core_ty.Any
which is not a type code.
type'a
pat ='a ty
Any
is a type pattern that can match any type.
It is not valid in contexts where a type code is expected: use only in contexts where a pattern is expected.val any : 'a pat
val pair : ('a * 'b) pat
val triple : ('a * 'b * 'c) pat
val quadruple : ('a * 'b * 'c * 'd) pat
val quintuple : ('a * 'b * 'c * 'd * 'e) pat
val sextuple : ('a * 'b * 'c * 'd * 'e * 'f) pat
val septuple : ('a * 'b * 'c * 'd * 'e * 'f * 'g) pat
val octuple : ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h) pat
val nonuple : ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i) pat
val decuple : ('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h * 'i * 'j) pat
val option : 'a option pat
val list : 'a list pat
val array : 'a array pat
conpat
computes the constructor pattern of a type code:
it replaces all the parameters with Any
.
For instance:
conpat Int == Int
conpat (List Int) == List Any
conpat (Pair (String, List Int)) == Pair (Any, Any)
val conpat : 'a ty -> 'a pat
conpat
computes a constructor pattern:
conpat (Pair (Int, List String)) == Pair (Any,Any)
val conpat' : ty' -> ty'
conpat'
is the ty'
version of conpat
, working on index-less type codes.
conpat' (E t) == E (conpat t)
Dynamically typed languages have a notion of runtime types which we can
emulate by packaging type witnesses with the values.
module Typed:sig
..end
type'a
typed ='a Typed.typed
type '_
ty +=
| |
Typed : |
module Dynamic:sig
..end
typedynamic =
Dynamic.dynamic
=
| |
Dyn : |
typedyn =
dynamic
type '_
ty +=
| |
Dynamic : |