Liquidsoap_lang.Type_baseType information comes attached to the AST from the parsing, with appropriate sharing of the type variables. Then the type inference performs in-place unification.
In order to report precise type error messages, we put very dense parsing location information in the type. Every layer of it can have a location. Destructive unification introduces links in such a way that the old location is still accessible.
The level annotation represents the number of abstractions which surround the type in the AST -- function arguments and let-in definitions. It is used to safely generalize types.
Finally, constraints can be attached to existential (unknown, '_a) and universal ('a) type variables.
Type description
module R : sig ... endA type constructor applied to arguments (e.g. source).
Contents of a variable.
and meth = {meth : string;name of the method
*)optional : bool;is the method optional?
*)scheme : scheme;type scheme
*)doc : meth_doc;documentation
*)json_name : string option;name when represented as JSON
*)}A method.
and custom_handler = {typ : custom;custom_name : string;copy_with : (t -> t) -> custom -> custom;occur_check : (t -> unit) -> custom -> unit;filter_vars : (var list -> t -> var list) -> var list -> custom -> var list;repr : (var list -> t -> constr R.t) -> var list -> custom -> constr R.t;subtype : (t -> t -> unit) -> custom -> custom -> unit;sup : (t -> t -> t) -> custom -> custom -> custom;to_string : custom -> string;}and descr = | String| Int| Float| Bool| Never| Custom of custom_handler| Constr of constructed| Getter of ta getter: something that is either a t or () -> t
*)| List of repr_t| Tuple of t list| Nullable of tsomething that is either t or null
*)| Meth of meth * tt with a method added
*)| Arrow of t argument list * ta function
*)| Var of var_ta type variable
*)module Constraints : sig ... endmodule DS : sig ... endval string_of_constr : constr -> stringexception Exists of Pos.Option.t * stringval unit : descrmodule Var : sig ... endOperations on variables.
module Vars : sig ... endSets of variables.
val make : ?pos:Pos.Option.base -> descr -> tCreate a type from its value.
Dereferencing gives you the meaning of a term, going through links created by instantiations. One should (almost) never work on a non-dereferenced type.
val has_meth : t -> string -> boolDo we have a method with given label?
val meth :
?pos:Pos.Option.base ->
?json_name:string ->
?category:[ `Callback | `Method ] ->
?optional:bool ->
string ->
scheme ->
?doc:string ->
t ->
tAdd a method to a type.
val meths :
?invoke:(t -> string -> scheme) ->
?pos:Pos.Option.base ->
string list ->
scheme ->
t ->
tAdd a submethod to a type.
val var :
?constraints:constr list ->
?level:int ->
?pos:Pos.Option.base ->
unit ->
tmodule Fresh : sig ... endval is_fun : t -> boolval is_source : t -> boolval custom_types : (string, unit -> t) Stdlib.Hashtbl.tval register_type : string -> (unit -> t) -> unitval find_opt_typ : string -> (unit -> t) optionval mk_invariant : t -> unit