Type and mode declarations for compiler-generated field access functions for fields of constructors local to a module may be placed in the interface section of the module. This allows the implementation of a type to be hidden while still allowing client modules to use record syntax to manipulate values of the type. Supplying a type declaration and a single mode declaration also allows higher-order terms to be created from a field access function without using explicit lambda expressions.
Declarations for field access functions for fields occurring in the interface section of a module must also occur in the interface section.
Declarations and clauses for field access functions can also be supplied for fields which are not a part of any type. This is useful when the data structures of a program change so that a value which was previously stored as part of a type is now computed each time it is requested. It also allows record syntax to be used for type class methods.
User-declared field access functions may take extra arguments.
For example, the Mercury standard library module map contains
the following functions:
:- func elem(K, map(K, V)) = V is semidet.
:- func 'elem :='(K, map(K, V), V) = map(K, V).
Field access syntax may be used at the top-level of func and
mode declarations and in the head of clauses. For instance:
:- func map(K, V) ^ elem(K) = V.
:- mode in ^ in = out is semidet.
Map ^ elem(Key) = map.lookup(Map, Key).
:- func (map(K, V) ^ elem(K) := V) = V.
:- mode (in ^ in := in) = out is semidet.
(Map ^ elem(Key) := Value) = map.set(Map, Key, Value).
The Mercury standard library modules array and bt_array
define similar functions.