Rex Type System (rexlang-typesystem)
This crate implements a Hindley-Milner style type system with parametric polymorphism, type classes, and simple algebraic data types (ADTs). It is intended to power Rex's checker and can also be reused by host code to register additional builtins or domain-specific types.
Features
- Types: primitives (
u8,u16,u32,u64,i8,i16,i32,i64,f32,f64,bool,string,uuid,datetime), tuples, functions, dictionaries (Dict a), and user constructors (List,Result,Option). - Arrays: host-native
Array avalues intended for performance and supported by the same collection combinators via type classes. - Schemes: quantified types with class constraints.
- Type classes: class hierarchy for additive/multiplicative monoids, semiring, additive group, ring, and field, plus instance resolution with superclass propagation.
- Prelude: ADT constructors (
Empty,Cons,Ok,Err,Some,None) and constrained function declarations for numeric, equality, list, option, and result operations. - Utilities: substitution, unification (with occurs check), instantiation, and generalization helpers.
Quickstart
use intern;
use ;
Inference
The inference entry points are infer(&mut ts, expr) (predicates + type) and infer_typed(&mut ts, expr) (typed AST + predicates + type), both of which work on rex_ast::expr::Expr. Literal behavior follows the current language requirement:
The inference engine and its tests live in src/inference.rs; src/typesystem.rs contains the shared type-system data structures, unification machinery, and declaration/typeclass registration code that inference builds on.
- Integer literals are
Integral-constrained and can specialize from context; ambiguous cases default later toi32 - Float literals default to
f32
Example (from tests):
let
id = \x -> x
in
id (id 420, id 6.9, id "str")
This infers to the tuple type (i32, f32, string).
The current inference implementation covers variables, application, lambdas, let-in, if-then-else, tuples, lists, dicts, named constructors, literals, and match.
Prelude Summary
Classes
AdditiveMonoid,MultiplicativeMonoid,Semiring,AdditiveGroup,Ring,FieldEq(equality),Ord(ordering)Functor,Applicative,Monad,Foldable,Filterable,Sequence,Alternative
Operators
- Arithmetic:
+,-,*,/,negate - Equality:
==,!=(Eq aconstraints) - Ordering:
<,<=,>,>=(Ord aconstraints) - Booleans:
&&,||(bool only) - Monoid identities:
zero,one
Collection Combinators
map,fold,foldl,foldr,filter,filter_map,bind,ap,or_elsesum,mean,count,take,skip,zip,unzip,min,maxThese are type-class constrained and work forList,Array,Option, andResultwhere applicable.
Option/Result Helpers
- Option:
is_some,is_none - Result:
is_ok,is_err
Run the library tests with:
Extending
You can register new ADTs with AdtDecl + TypeSystem::register_adt. The TypeSystem also exposes register_instance for low-level instance-head injection and a supply for generating fresh type variables when building new schemes.