所以我对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.
或者那完全没问题吗?只是想看看是否有任何明显的方法来改进我错过的上述代码。
感谢。
答案 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).