Prolog-遍历列表

9
假设我有一个列表 Xs = [a,b,c],现在我想要遍历所有元素,并对这些元素调用另一个函数。我的问题是:如何使用头和尾来实现这个功能?感谢您的帮助。

首先,map 是你的好朋友。 - therealprashant
如果您移除headtail的限制,您可以通过使用fail和析取来简单地遍历列表元素: member(X, [1,2,3,4]), writeln(X), fail; true. 将逐个打印列表元素,并且目标将会成功。 - Fibo Kowalsky
1个回答

27

通常情况下,你不会在Prolog中进行迭代。相反,你需要编写一对递归子句的规则,如下所示:

 dosomething([]).
 dosomething([H|T]) :- process(H), dosomething(T).

第一条规则处理基本情况,即当列表 [] 为空时。这种情况下,没有任何操作需要执行,因此该规则的主体也是空的。
第二条规则处理列表至少有一个元素的情况。语法 [H | T] 与列表进行统一,使得 H 成为列表的头部,而 T 成为其尾部。例如,如果处理 dosomething([a,b,c]),则 H 变成 a,而 T 变成 [b,c]
该规则的主体由两个部分组成。第一部分针对头部进行操作,调用 process。这是你想要对列表的每个元素执行的规则。第二部分在列表的尾部上递归调用 dosomething 规则。当尾部列表不为空时,dosomething 的第二条规则将与更短的列表相统一以继续处理。当尾部列表为空时,第一条规则将相统一,从而结束处理过程。

11
虽然这个回答是正确的,但它很像20世纪70年代的风格。与此同时,现在有maplist(process, [a,b,c])maplist/3maplist/4等函数。 - false
9
您说得非常正确。然而,OP 想知道“如何使用 head 和 tail 实现此操作”,因此我解释了上世纪的实现方法。我认为深入理解这个简单的代码片段对理解 Prolog 的处理方式非常重要。当然,Prolog 实践者很快就会发现 maplist/2,并且永远不会回头。 - Sergey Kalinichenko
2
虽然我们应该在这里回答提出的问题,但这些问题通常包含一些最好被忽略的部分。 - false

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接