This assignment operator introduces a domain-specific language for specifying
new types. Types are defined by the ways they can be constructed. This is
provided as a sequence of |
-separated constructors, where a
constructor is either a constant, i.e., a bare symbol, or a function.
":="(data_type, constructors)
data_type | The name of the new data type. Should be given as a bare symbol. |
---|---|
constructors | A list of |
We can construct an enumeration like this:
numbers := ONE | TWO | THREE
This will create the type numbers
and three constants, ONE
,
TWO
, and THREE
that can be matched against using the
case_func
function.
f <- case_func(ONE -> 1, TWO -> 2, THREE -> 3)
x <- TWO
f(x)
Evaluating functions declared using the case_func
function will compare the value in
x
against the three patterns and recognize that x
holds the
constant TWO
and it will then return 2
.
With function constructors we can create more interesting data types. For example, we can create a linked list like this
linked_list := NIL | CONS(car, cdr : linked_list)
This expression defines constant NIL
and function CONS
. The
function takes two arguments, car
and cdr
, and requires that
cdr
has type linked_list
. We can create a list with three
elements, 1, 2, and 3, by writing
CONS(1, CONS(2, CONS(3, NIL)))
and we can, e.g., test if a list is empty using
f <- case_func(NIL -> TRUE, CONS(car,cdr) -> FALSE)
f(lst)
A variable will be bound to any value, and you can exploit this to
get a default return value. I prefer to use .
f <- case_func(NIL -> TRUE, . -> FALSE)
f(lst)
Arguments to a constructor function can be typed. To specify typed variables,
we use the :
-operator. The syntax is then var : type
. The type
will be checked when you construct a value using the constructor.
linked_list := NIL | CONS(car, cdr : linked_list) lst <- CONS(1, CONS(2, CONS(3, NIL))) len <- case_func(acc = 0, NIL -> acc, CONS(car,cdr) -> len(cdr, acc + 1) ) len(lst)#> [1] 3list_sum <- case_func(acc = 0, NIL -> acc, CONS(car,cdr) -> list_sum(cdr, acc + car) ) list_sum(lst)#> [1] 6