只有当人们知道它的含义时,它才易于理解,并且可能应该重做。
:-meta_predicate maplist(2, ?, ?).
...只是意味着“2”位置上的参数将用作将被调用的谓词的内核。我们对此没有特殊的符号(恕我直言,这是一个很大的错误),因此我们将以标准方式将其写为f(foo,bar)
, 或f(foo)
, or之类的术语f
。元谓词将maplist/3
如何处理该术语?好吧,它将在语法上对其进行转换并在其末尾添加“2”个附加参数(并且仅在其末尾,这会导致尴尬):f(foo,bar, ARG1,ARG2)
, or f(foo, ARG1,ARG2)
, or 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.
以上内容与 Paulo Moura's 结合使用实际上可以使用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 标准中严重缺失的 Lambda 表达式提供了适当的语法,以明确显示缺失的参数。
很久以前人们可以想象有这样的表达方式:
?- maplist(λX.verify(3,X), [1,2,3,4,5]).
或者留在 ASCIIland,比如:
?- maplist(\X.verify(3,X), [1,2,3,4,5]).
但它没有发生。