Next: Higher-order insts and modes, Previous: Creating higher-order terms, Up: Higher-order [Contents]

Once you have created a higher-order predicate term (sometimes known as a closure), the next thing you want to do is to call it. For predicates, you use the builtin goal call/N:

`call(Closure)`

`call(Closure1, Arg1)`

`call(Closure2, Arg1, Arg2)`

- …
A higher-order predicate call. ‘

`call(Closure)`’ just calls the specified higher-order predicate term. The other forms append the specified arguments onto the argument list of the closure before calling it.

For example, the goal

call(Sum123, Result)

would bind `Result`

to the sum of ‘`[1, 2, 3]`’, i.e. to 6.

For functions, you use the builtin expression apply/N:

`apply(Closure)`

`apply(Closure1, Arg1)`

`apply(Closure2, Arg1, Arg2)`

- …
A higher-order function application. Such a term denotes the result of invoking the specified higher-order function term with the specified arguments.

For example, given the definition of ‘`Double`’ above, the goal

List = apply(Double, [1, 2, 3])

would be equivalent to

List = scalar_product(2, [1, 2, 3])

and so for a suitable implementation of the function ‘`scalar_product/2`’
this would bind `List`

to ‘`[2, 4, 6]`’.

One extremely useful higher-order predicate in the Mercury standard library
is ‘`solutions/2`’, which has the following declaration:

:- pred solutions(pred(T), list(T)). :- mode solutions(pred(out) is nondet, out) is det.

The term which you pass to ‘`solutions/2`’ is a higher-order predicate term.
You can pass the name of a one-argument predicate,
or you can pass a several-argument predicate
with all but one of the arguments supplied (a closure).
The declarative semantics of ‘`solutions/2`’ can be defined as follows:

solutions(Pred, List) is true iff all [X] (call(Pred, X) <=> list.member(X, List)) and List is sorted.

where ‘`call(Pred, X)`’
invokes the higher-order predicate term `Pred`

with argument `X`

,
and where ‘`list.member/2`’
is the standard library predicate for list membership.
In other words, ‘`solutions(Pred, List)`’ finds all the values of `X`

for which ‘`call(Pred, X)`’ is true,
collects these solutions in a list,
sorts the list, and returns that list as its result.
Here is an example: the standard library defines a predicate
‘`list.perm(List0, List)`’

:- pred list.perm(list(T), list(T)). :- mode list.perm(in, out) is nondet.

which succeeds iff List is a permutation of List0. Hence the following call to solutions

solutions(list.perm([3,1,2]), L)

should return
all the possible permutations of the list ‘`[3,1,2]`’ in sorted order:

L = [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]].

See also ‘`unsorted_solutions/2`’ and ‘`solutions_set/2`’,
which are defined in the standard library module ‘`solutions`’
and documented in the Mercury Library Reference Manual.