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’s 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.