Higher-Order & Meta Predicates
Variables in lambda bodies are copied unless declared free with \ or / — a frequent gotcha; or define a helper predicate instead.
22.1 call/N
?- G = format("~w~n", [hi]), call(G).
?- P = succ, call(P, 3, X). % X = 4
twice(G, X, Z) :- call(G, X, Y), call(G, Y, Z).
?- twice(succ, 1, R). % R = 322.2 library(apply)
?- maplist(succ, [1, 2, 3], L). % L = [2, 3, 4]
?- maplist([X, Y]>>(Y is X * X), [1, 2, 3], L). % yall lambda: L = [1, 4, 9]
?- maplist(=(0), L), length(L, 3). % L = [0, 0, 0]
?- maplist([X]>>(X > 0), [1, 2]). % check all
?- maplist([X, Y, Z]>>(Z is X + Y), [1, 2], [10, 20], S). % zipWith: S = [11, 22]
?- include([X]>>(X mod 2 =:= 0), [1, 2, 3, 4], E). % E = [2, 4]
?- exclude([X]>>(X > 2), [1, 2, 3], R). % R = [1, 2]
?- partition([X]>>(X < 3), [1, 5, 2, 4], In, Out).
?- foldl([X, A0, A]>>(A is A0 + X), [1, 2, 3], 0, Sum). % Sum = 6
?- aggregate_all(count, member(_, [a, b]), N).22.3 Lambdas: library(yall)
Variables in lambda bodies are copied unless declared free with \ or / — a frequent gotcha; or define a helper predicate instead.
[X]>>Goal % parameters
\X^Goal % lambda with local variable
/(Free, [X]>>Goal) % Free variables shared with context: Free/[X]>>Goaladd_n(N, L0, L) :- maplist([X, Y]>>(Y is X + N), L0, L). % N is captured (copy semantics apply!)22.4 Meta-predicate declarations
The number tells how many extra arguments are added; : means module-sensitive; ^ for bagof-style; // for DCG bodies. Needed so goals are resolved in the caller's module.
:- meta_predicate apply_twice(1, ?).
apply_twice(G, X) :- call(G, X), call(G, X).22.5 Goals as data
run_all([]).
run_all([G|Gs]) :- call(G), run_all(Gs).
?- run_all([X = 1, Y is X + 1, writeln(Y)]).