Module Smyth.Type
Helpers
val equal : Lang.typ -> Lang.typ -> bool
equal tau1 tau2
determines iftau1
andtau2
have the same abstract syntax tree.
val wildcard : Lang.typ
The "wildcard" type.
val matches : Lang.typ -> Lang.typ -> bool
matches tau1 tau2
determines iftau1
andtau2
have the same abstract syntax tree modulo any wildcards.
val is_base : Lang.typ -> bool
is_base tau
returns determines iftau
is a base type.
val domain_of_codomain : codomain:Lang.typ -> Lang.typ -> Lang.typ option
domain_of_codomain ~codomain root
looks forcodomain
on the right-hand side of a type arrow inroot
that is not on the left-hand side of any type arrow and, if found, returns the left-hand side of that type arrow.For example, suppose
tau = a -> (b -> (c -> d))
. Then:domain_of_codomain ~codomain:d tau = Some c domain_of_codomain ~codomain:(c -> d) tau = Some b domain_of_codomain ~codomain:(b -> (c -> d)) tau = Some a domain_of_codomain ~codomain:(a -> (b -> (c -> d))) tau = None
Also:
domain_of_codomain ~codomain:a a = None domain_of_codomain ~codomain:a (() -> a) = Some ()
val bind_spec : Lang.type_ctx -> Lang.exp -> Lang.bind_spec
bind_spec gamma e
returns the computed binding specification ofe
with respect togamma
. In particular:- Projections decrease the binding specification of their argument
- Variables are looked up in
gamma
val sub_bind_spec : Lang.bind_spec -> Lang.bind_spec
sub_bind_spec b
"decreases" the binding specificationb
. In particular, ifb
is a binding specification for the argument of some function, thensub_bind_spec b
will be a binding specification for decreasing on that function.
val structurally_decreasing_bind_spec : head_spec:Lang.bind_spec -> arg_spec:Lang.bind_spec -> bool
structurally_decreasing_bind_spec ~head_spec ~arg_spec
determines ifarg_spec
is decreasing onhead_spec
. Ifhead_spec
is not a binding specification for a recursive function, thenstructurally_decreasing ~head_spec ~arg_spec
will returntrue
.
val structurally_decreasing : Lang.type_ctx -> head:Lang.exp -> arg:Lang.exp -> bool
structurally_decreasing gamma ~head ~arg
determines ifarg
is structurally decreasing onhead
in the contextgamma
.
val matches_dec : string option -> Lang.bind_spec -> bool
matches_dec (Some f) bind_spec
determines ifbind_spec
is structurally decreasing on the recursive functionf
.matches_dec None bind_spec
will always returntrue
.
val peel_forall : Lang.typ -> string list * Lang.typ
Peels all outer universal quantifiers on a type into a list. For example:
peel_forall (forall a . forall b . a * b) = (["a", "b"], a * b) peel_forall a = ([], a) peel_forall (int * int) = ([], int * int) peel_forall (forall c . int) = (["c"], int) peel_forall (forall c . d) = (["c"], d)
Substitution
val substitute : before:string -> after:Lang.typ -> Lang.typ -> Lang.typ
substitute ~before ~after tau
substitutes replaces free occurrences ofbefore
intau
withafter
.
val substitute_many : bindings:(string * Lang.typ) list -> Lang.typ -> Lang.typ
Performs many substitutions one after another; see
substitute
.
Type-checking
The following functions implement a bidirectional type checker.
type error
=
|
VarNotFound of string
|
CtorNotFound of string
|
PatternMatchFailure of Lang.typ * Lang.pat
|
WrongNumberOfTypeArguments of int * int
|
GotFunctionButExpected of Lang.typ
|
GotTupleButExpected of Lang.typ
|
GotTypeAbstractionButExpected of Lang.typ
|
GotButExpected of Lang.typ * Lang.typ
|
BranchMismatch of string * string
|
CannotInferFunctionType
|
CannotInferCaseType
|
CannotInferHoleType
|
ExpectedArrowButGot of Lang.typ
|
ExpectedTupleButGot of Lang.typ
|
ExpectedForallButGot of Lang.typ
|
ExpectedDatatypeButGot of Lang.typ
|
TupleLengthMismatch of Lang.typ
|
ProjectionLengthMismatch of Lang.typ
|
ProjectionOutOfBounds of int * int
|
TypeAbstractionParameterNameMismatch of string * string
|
AssertionTypeMismatch of Lang.typ * Lang.typ
Type-checking errors.
val check : Lang.datatype_ctx -> Lang.type_ctx -> Lang.exp -> Lang.typ -> (Lang.hole_ctx, Lang.exp * error) Stdlib.result
Bidirectional type "checking".
val infer : Lang.datatype_ctx -> Lang.type_ctx -> Lang.exp -> (Lang.typ * Lang.hole_ctx, Lang.exp * error) Stdlib.result
Bidirectional type "inference" or "synthesis".