在prolog中添加列表的元素

时间:2017-04-10 16:00:40

标签: list prolog

所以我对prolog很新,我必须添加列表的所有元素。

listSum([],0).
listSum([Head|Tail], Sum) :- listSum(Tail,TailSum), Sum is Head + TailSum.

目标是使这个尾递归,我想知道这是否是一个比这更好的方法

listSum([],0).
listSum(List, Sum) :- listSum(List,Sum,0).
listSum([H|T], Sum, S) :- S1 is S+H, listSum(T, Sum, S1).
listSum([], Sum, S) :- Sum is S.

或者那完全没问题吗?只是想看看是否有任何明显的方法来改进我错过的上述代码。

感谢。

1 个答案:

答案 0 :(得分:2)

这对我来说非常好。你可以通过不做不必要的事情来节省一些自己的写作。首先,你从两个不同的地方得到0;从一个人那里得到它就足够了。此外,"输出"参数应该在所有其他参数之后出现。

list_sum(L, S) :-
    list_sum(L, 0, S).

然后,你不需要基本情况​​下的is/2

list_sum([], S, S).
list_sum([X|Xs], S0, S) :-
    S1 is S0 + X,
    list_sum(Xs, S1, S).

当然,您可以决定在尾递归定义中实际保存一步:

list_sum([], 0).
list_sum([X|Xs], S) :-
    list_sum(Xs, X, S).

list_sum([], S0, S) :- S is S0.
list_sum([X|Xs], S0, S) :-
    S1 is S0 + X,
    list_sum(Xs, S1, S).

你应该认识到第二个版本是折叠:

list_sum([], 0).
list_sum([X|Xs], S) :-
    foldl(add, Xs, X, S).

add(X, Y, S) :- S is X+Y.

或者,甚至直接:

list_sum(List, Sum) :- foldl(add, List, 0, Sum).