## Tuesday, October 23, 2007

### Discriminated unions in Mercury

While reading the Mercury tutorial I learned how to define discriminated unions or algebraic datatypes.

Discriminated unions provide a way to define new structured data types.

For example here's a couple of type definitions that represent very simple arithmetic expressions:

``:- type expression --->  const(int)                   ; var(string)                   ; binaryOperation(expression,operator,expression).:- type operator ---> add ; subtract.``

These definitions specify arithmetic expression parts such as constants(`const`), variables(`var`), binary operations(`binaryOperation`), etc.

Given these definitions we can instantiate them by calling the constructors:

``main(!IO) :-   X = binaryOperation(var("x"),add,const(10)),``

Also we can use Mercury's unification to easily manipulate them, for example the following function writes the content of the expression to the output:

``:- func operator_to_string(operator) = string.operator_to_string(add)       = "+".operator_to_string(subtract)  = "-".:- pred write_expression(expression::in,io::di,io::uo) is det.write_expression(const(C),!IO) :-   io.write_int(C,!IO).write_expression(var(S),!IO) :-   io.write_string(S,!IO).write_expression(binaryOperation(Operand1,Operator,Operand2) ,!IO) :-   write_expression(Operand1,!IO),   io.write_string(operator_to_string(Operator),!IO),   write_expression(Operand2,!IO).``

Calling this predicate like this:

``main(!IO) :-   X = binaryOperation(var("x"),add,const(10)),   write_expression(X,!IO).``

Generates:
``x+10``