-
Notifications
You must be signed in to change notification settings - Fork 54
Equivalence types
Equivalence types give alternative names to existing types. Usually they are used to give a complex type a shorter name, or to give the use of a general type a more specific name.
Equivalence types are introduced with ==
like this:
:- type radius == float.
:- type assoc_list(K, V) == list(pair(K, V))
As in the second example, equivalence types may be polymorphic.
Type variables in the body of the definition must appear as arguments
on the left of the ==
.
Mercury treats an equivalence type as an abbreviation for the type on the right hand side of the definition; the two are equivalent in all respects in scopes where the equivalence type is visible.
Equivalence types have their uses, but it is often better to introduce new types so that two unrelated types cannot be confused.
For example, an application program might need to identify customers and orders with integers.
:- type customer_id == int.
:- type order_id == int.
This is reasonable, but leaves the potential for mistakes to occur.
Customer and order numbers could be swapped or confused for any other
int
, and the type checker would not tell you anything.
We can improve the situation by introducing new types instead:
:- type customer_id
---> customer_id(int).
:- type order_id
---> order_id(int).
There is no difference in the run-time data representation (at least, when targeting C) compared to the equivalence type definitions; the difference only exists at the type level.