下面的元谓词通常很有用。请注意,它不能被称为maplist//2
,因为它的扩展将与maplist/4
冲突。
maplistDCG(_P_2, []) -->
[].
maplistDCG(P_2, [A|As]) -->
{call(P_2, A, B)},
[B],
maplistDCG(P_2, As).
这里有几个问题。当然是名字。但终端[B]
:它是否应该明确地与连接目标断开连接?
在没有上述定义的情况下,必须写出以下其中一个——两者都有严重的终止问题。
maplistDCG1(P_2, As) -->
{maplist(P_2, As, Bs)},
seq(Bs).
maplistDCG2(P_2, As) -->
seq(Bs),
{maplist(P_2, As, Bs)}.
seq([]) -->
[].
seq([E|Es]) -->
[E],
seq(Es).
{call(P_2,A,B)}, [B]
比[B], {call(P_2,A,B)}
有优势吗
(如果是的话,maplist/3
不应该也得到这样的东西吗?)
让我们将相应的dcg和非dcg变体并排放置1:
-
dcg
[B],{call(P_2,A,B)}
和非dcgBs0 = [B|Bs], call(P_2,A,B)
地图列表DCG(_,[])-->[].%地图列表(_,[],[])。映射列表DCG(P_2,[A|As])-->%映射列表(P_2、[A|As]Bs0):-[B] ,%Bs0=[B|Bs],{调用(P_2,A,B)},%调用(P_1,A),映射列表DCG(P_2,As)。%映射列表(P_2,As,Bs)。
-
dcg
{call(P_2,A,B)},[B]
和非dcgcall(P_2,A,B), Bs0 = [B|Bs]
地图列表DCG(_,[])-->[].%地图列表(_,[],[])。映射列表DCG(P_2,[A|As])-->%映射列表(P_2、[A|As],Bs0):-{call(P_2,A,b)},%call(P_2、A、b),[B] ,%Bs0=[b|Bs],映射列表DCG(P_2,As)。%映射列表(P_2,As,Bs)。
上面,我们强调了现在使用的目标排序:
- 由
maplist/3
,如SO上的这个答案和Prolog序言中所定义 - 由
maplistDCG//2
,如OP在本问题中所定义
如果我们考虑到。。。
-
。。。需要考虑终止属性,并且。。。
-
。。。dcg和非dcg变体应该更好地表现出相同的2。。。
我们发现变量应该而不是与连接目标显式断开连接。maplist/3
的天然DCG类似物是maplistDCG//2
,定义如下:
maplistDCG(_,[]) -->
[].
maplistDCG(P_2,[A|As]) -->
[B],
{call(P_2,A,B)},
maplistDCG(P_2,As).
脚注1:为了强调共性,我们调整了变量名、代码布局,并明确了一些统一性脚注2:。。。除非我们对他们的分歧行为有充分的理由