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).