Documentation for the Polymorphic Set-Theoretic type-system prototype

Basic usage
Syntax of the language
Caveat

Basic usage

The prototype consists of an online text editor (based on Monaco Editor).

Computed types are printed as lenses (above each definition). In case of error, the error message is printed instead (see the caveat section for the printing format).

Syntax

Definitions

A program is a sequence of toplevel statements:
prog ::= stmt* stmt ::= type tid tvar* = t [and ...] | atoms id+ | let gid : t = e | let [rec] gid param* = e | let [rec] (gid : t) param* = e param ::= pat [: t, ...,t]

A statement can be either

Identifiers

Identifiers come in several flavours :

gid ::= id | ( op ) id ::= [a-z_][a-zA-Z0-9_']* tid ::= [A-Z][a-zA-Z0-9_']* tvar ::= '[a-z_][a-zA-Z0-9_]*

Type expressions

t ::= simple_type | t -> t | t , t | [ tregex ] | { id =[?] t,..., id =[?] t [..]} | t | t | t & t | t \\ t | ~ t | t where tid tvar* = t [and ...] simple_type ::= b | tid [t ... t] | tvar | (t) b ::= () | lit | int--int | (--int) | int--) | (--) | Any | Empty | True | False | Bool | Int | Char | Unit | String | List | Nil

Types are the usual set-theoretic types with product and arrow and record constructors and union, intersection, difference and negation operators. A sequence type constructor is provided as well. The content of a sequence type can be a regular expression over types, using the usual operators (*, + and ?). For instance, the type [ 'a* (Bool|Int)? ] is equivalent to the type definition

type t 'a = ('a, t) | s and s = Nil | (Bool | Int, Nil)

Record types are given by the list of their fields, that is labels associated with a type. A label may be absent (denoted by =?). Open record types end their field list with ... Polymorphic types can be instantiated by giving a list of type parameters. Basic types consists of literals (which denote their own singleton type), augmented with integer interval types, and set of builtin type identifiers.

Expressions

e ::= lit | gid | magic | (e : t ; ... ; t ) | (e :> t ; ... ; t ) | { [e with] id=e,...,id=e} | [ e; ... ;e ] | e,e | fun param ... param -> e | let gid = e in e | let (pat) = e in e | if e [is t] then e else e | fst e | snd e | match e with [|] pat -> e | ... | pat -> e end lit ::= [0-9]+ | 'char' | "char*" | float | () | unit | false | true | nil

Expressions can be

Patterns

pat ::= :simple_type | id | pat,pat | pat|pat | pat&pat | (pat) | [ pat; ... ;pat ] | { id =[?] pat,..., id =[?] pat [..]} | id = lit

Patterns are essentially types with capture variables. For instance, the following expression

match y with | :[ Int* ] -> false | ( x & :Bool, :Int ) | x = false -> x end

First checks whether y is a list of integers, in which case it returns false. Or, it tests whether either y is a pair of a Boolean and an integer, and captures the Boolean in x, or defines x to the constant false, and then returns x.

Caveat