Overview
In MUFL the convention is to treat containers as functions, consequently, MUFL has three flavors of functional types:
- Reduceable - functions, represented by the
->syntax. - Mutable - dictionaries, represented by the
->>syntax. Mutable types, by definition, are both scannable and reduceable. - Scannable - types that can be iterated over using the
scanstatement, represented by the*>syntax.
Reduceable Types
Reduceable types are those which may be used in a reduction expression a b. These are functions and dictionaries (also strings and binaries). Reduceable types are represented by type expression reducer->product, where the reducer is the type of argument in the reduction expression and product is the type of the result of the reduction expression.
Example:
ToString = fn a:int = (_str a).
IntToStrFunc is int->str = ToString. // compatible because ToString takes int and returns str
ResultFor10 is str = IntToStrFunc 10. // compatible because product is of type str
Functional type operations are right-associative, so to declare a function of three arguments using this syntax you use the expression
arg1->arg2->arg3->ret.
Scannable Types
Scannable types refer to those types that can be used in a scan statement. They are represented by the *> type expression.
For example, the INTEGER_SEQUENCE domain maps to the scannable type int*>int. Integer sequences are scannable, but not reduceable.
Mutable Types
Mutable types refer to dictionaries and are represented by type expression reducer->>product. Mutability implies reduceability, so a->b is compatible with a->>b but not vice versa. Similarly, mutability implies scannability.
Mutable types indicate a value to which the mutation operator -> can be applied.