Это формулировка, которую легко понять, только когда известно, что это значит, и, вероятно, ее следует переделать.
:-meta_predicate maplist(2, ?, ?).
... просто означает, что аргумент на месте "2 будет использоваться в качестве ядра предиката, который будет вызываться. У нас нет специальных обозначений для этого (большая ошибка, ИМХО), поэтому мы напишем это стандартным образом как термин типа f(foo,bar)
, или f(foo)
, или f
. Что мета-предикат maplist/3
будет делать с этим термином? Что ж, он синтаксически преобразует его и добавит «2» дополнительных аргументов на своем конце (и только на своем конце, что приводит к неловкости): f(foo,bar, ARG1,ARG2)
, или f(foo, ARG1,ARG2)
, или f(ARG1,ARG2)
. Тогда maplist/3
вызовет его.
Например, для вышеупомянутого maplist/3
, возьмите этот предикат, принимая два аргумента:
myprint(X,Y)
:- format("~w\n",[(X,Y)]).
Может использоваться в таком вызове maplist/3
без указания каких-либо аргументов:
maplist(myprint,[0,1,2,3],[a,b,c,d]).
и два аргумента, по одному из каждого списка, будут добавлены в термин myprint
, прежде чем этот термин будет посвящен в рыцари, чтобы стать предикатом и называется:
?- maplist(myprint,[0,1,2,3],[a,b,c,d]).
0,a
1,b
2,c
3,d
true.
Это позволяет пропускать «частично заполненные вызовы». maplist/2
прикрепит 1 аргумент к концу своего первого аргумента, поэтому можно сказать:
?- maplist(myprint("foo+"),[a,b,c,d]).
foo+,a
foo+,b
foo+,c
foo+,d
true.
Вышеприведенное становится фактически пригодным для использования в сочетании с library(yall)
Пауло Моуры, который оборачивает цель в анонимный предикат, выставляя аргументы. Тогда можно гибко переставить вещи
?- maplist([X,Y]>>format("~w\n",[(X,Y)]),[0,1,2,3],[a,b,c,d]).
0,a
1,b
2,c
3,d
true.
?- maplist([Y,X]>>format("~w\n",[(X,Y)]),[0,1,2,3],[a,b,c,d]).
a,0
b,1
c,2
d,3
true.
Фактически library(yall)
обеспечивает правильный синтаксис для лямбда-выражений, который безжалостно отсутствует в стандарте ISO, чтобы явно показывать отсутствующие параметры.
Кто-то мог представить себе такие длинные выражения go:
?- maplist(λX.verify(3,X), [1,2,3,4,5]).
или остаться в ASCIIland, что-то вроде:
?- maplist(\X.verify(3,X), [1,2,3,4,5]).
, но это не случилось.