Previous: User-supplied field access function declarations, Up: Field access functions   [Contents]


3.4.4 Field access examples

The examples make use of the following type declarations:

:- type type1
        --->    type1(
                    field1 :: type2,
                    field2 :: string
                ).

:- type type2
        --->    type2(
                    field3 :: int,
                    field4 :: int
                ).

The compiler generates some field access functions for ‘field1’. The functions generated for the other fields are similar.

:- func type1 ^ field1 = type2.
type1(Field1, _) ^ field1 = Field1.

:- func (type1 ^ field1 := type2) = type1.
(type1(_, Field2) ^ field1 := Field1) = type1(Field1, Field2).

Using these functions and the syntactic sugar described in Record syntax, programmers can write code such as

:- func type1 ^ increment_field3 = type1.

Term0 ^ increment_field3 =
    Term0 ^ field1 ^ field3 := Term0 ^ field1 ^ field3 + 1.

The compiler expands this into

increment_field3(Term0) = Term :-
    OldField3 = field3(field1(Term0)),
    OldField1 = field1(Term0),
    NewField1 = 'field3 :='(OldField1, OldField3 + 1),
    Term = 'field1 :='(Term0, NewField1).

The field access functions defined in the Mercury standard library module ‘map’ can be used as follows:

:- func update_field_in_map(map(int, type1), int, string)
    = map(int, type1) is semidet.

update_field_in_map(Map, Index, Value) =
    Map ^ elem(Index) ^ field2 := Value.