type x[U,V] .. fun f[U,V] .. proc g[U,V] .. class k[U,V] .. struct s[U,V] .. union u[U,V] .. cstruct c[U,V] .. cclass k[U,B] ..All such definitions are intrinsically polymorphic: the lack of an explicit schema designator:
fun f(x:int)=>x;is simply shorthand for a unit schema:
fun f[](x:int)=>x;
In addition, modules may also have type schema, however this is just sugar. The semantics are to prepend the schema to the schema of every definition in the module:
module X[T] { fun f(x:int)=>x; fun g[U](x:int)=>x; }is equivalent to:
module X { fun f[T](x:int)=>x; fun g[T,U](x:int)=>x; }
In addition, typdefs may have schema:
typedef pair[T] = T * T;Such a parameterised type alias is a special kind of type function or type functor:
typedef fun pair(T:TYPE):TYPE => T * T;
Type schema parameters also individual constraints:
fun f[I:fast_sints] ..says that the type variable I must be instantiated with a member of the typeset of fast_sints. Discrete typesets can be named by a typedef:
typedef fast_sints = typesetof (tiny, short, int, long, vlong);The union and intersection of such sets may be calculated with the setwise union and intersection operators:
typedef A = B || C && D;with the usual precedence.