Mercury's Type System --------------------- The type system is based on a polymorphic many-sorted logic, similar to Goedel. But the syntax is different (in some respects better), we allow equivalence types, and we allow overloading of function symbols defined within the same module (Goedel only allows it if the function symbols are defined in different modules). There are two categories of builtin types: Primitive types: char, integer, float, string. These are automatically predefined, there is a special syntax for constants of these types, and there are infinitely many constants for some of these types. Predicate types: pred, pred(T), pred(T1, T2), ... These are used in higher-order code to pass predicates around. There are several categories of derived types: Discriminated unions: theses encompass both enumerations and records, and are defined as follows. :- type fruit ---> apple ; orange ; banana ; pear. :- type strange ---> foo(int) ; bar(string). :- type employee ---> employee( string, % name int, % age string % department ). :- type tree ---> empty ; leaf(int) ; branch(tree, tree). :- type list(T) ---> [] ; '.'(T, list(T)). :- type pair(T1, T2) ---> T1 - T2. Equivalent types: these are type abbreviations. They are defined using `==' as follows. :- type money == int. :- type assoc_list(KeyType, ValueType) == list(pair(KeyType, ValueType)). Abstract types: these are types whose implementation is hidden. The type declarations :- type t1. :- type t2(T1, T2). declare types `t1/0' and `t/2' to be abstract types. Such declarations are only useful in the interface section of a module. This means that the type names will be exported, but the constructors (constants and functors) for these types will not be exported.