Previous: Purity annotations on lambda expressions, Up: Higher-order impurity


15.8.3 Purity annotations on higher-order calls

Any calls to impure or semipure higher-order terms must be explicitly annotated as such. For impure or semipure higher-order predicates, the annotation is indicated by putting ‘impure’ or ‘semipure’ before the call. For example:

     	:- func foo(impure pred(int)) = int.
     	:- mode foo(in(pred(out) is det)) = out is det.
     
     	foo(ImpurePred) = X1 + X2 :-
     		% using higher-order syntax
     		impure ImpurePred(X1),
     		% using the call/N syntax
     		impure call(ImpurePred, X2).

For calling impure or semipure higher-order functions, the notation is different than what you might expect. In addition to using an ‘impure’ or ‘semipure’ operator on the unification which invokes the higher-order function application, you must also use ‘impure_apply’ or ‘semipure_apply’ rather than using ‘apply’ or higher-order syntax. For example:

     	:- func map(impure func(T1) = T2, list(T1)) = list(T2).
     
     	map(_ImpureFunc, []) = [].
     	map(ImpureFunc, [X|Xs]) = [Y|Ys] :-
     		impure Y = impure_apply(ImpureFunc, X),
     		impure Ys = map(ImpureFunc, Ys).