问题
In sicstus prolog, there's a predicate:
maplist(:Pred, +List)
Pred
is supposed to take just one argument - List
element. How can I pass a 2-argument predicate, with first argument defined? In other languages it would be written as:
maplist(pred.bind(SomeValue), List)
回答1:
maplist(P_1, Xs)
will call call(P_1, X)
for each element of Xs
. The built-in predicate call/2
adds one further argument to P_1
and then calls this with call/1
. To indicate that a further argument is needed, it is very helpful to use a name like P_1
meaning "one extra argument is needed".
So if you have already a predicate of arity 2, say, (=)/2
, you will pass =(2)
to maplist:
?- maplist(=(2), Xs).
Xs = [] ;
Xs = [2] ;
Xs = [2,2] ...
Since the definition in SICStus' library is unfortunately, incorrect, rather use the following definition:
:- meta_predicate(maplist(1,?)).
:- meta_predicate(maplist_i(?,1)).
maplist(P_1, Xs) :-
maplist_i(Xs, P_1).
maplist_i([], _P_1).
maplist_i([E|Es], P_1) :-
call(P_1, E),
maplist_i(Es, P_1).
See this answer for more.
Just a nice further example about lists of lists.
?- Xss = [[A],[B,C]], maplist(maplist(=(E)), Xss).
Xss = [[E], [E, E]],
A = B, B = C, C = E.
来源:https://stackoverflow.com/questions/30758763/prolog-binding-arguments