【发布时间】:2019-07-29 10:50:47
【问题描述】:
-module(test).
-export([sum/1]).
sum([]) -> 0;
sum([X|Xs]) -> X + sum(Xs)
这是我迄今为止所做的,尽管它只是将列表中的数字相加,如test:sum([1,2,3,4])
但我希望它像 test:sum(4) 一样输出 1+2...+n
我该怎么做?
【问题讨论】:
标签: erlang erlang-shell
-module(test).
-export([sum/1]).
sum([]) -> 0;
sum([X|Xs]) -> X + sum(Xs)
这是我迄今为止所做的,尽管它只是将列表中的数字相加,如test:sum([1,2,3,4])
但我希望它像 test:sum(4) 一样输出 1+2...+n
我该怎么做?
【问题讨论】:
标签: erlang erlang-shell
您提供的此函数将对列表中的值求和,但如果您想“重载”此函数以也支持整数,那么您可以编写:
-module(test).
-export([sum/1]).
sum([]) -> 0;
sum([X|Xs]) -> X + sum(Xs);
sum(0) -> 0;
sum(N) when is_integer(N) -> (N * (N + 1)) div 2.
这使用模式匹配来检查参数的类型,然后选择适当的函数“版本”进行评估。
【讨论】:
但我希望它像 test:sum(4) 一样输出 1+2...+n
这是一个递归解决方案:
-module(my).
-compile(export_all).
sum(0) ->
0;
sum(X) ->
X + sum(X-1).
在外壳中:
3> my:sum(1).
1
4> my:sum(2).
3
5> my:sum(3).
6
6> my:sum(4).
10
7> my:sum(5).
15
请注意,如果您使用负数调用 sum/1,sum/1 将永远递归并最终使 shell 崩溃,因此您可以添加一个守卫以仅接受正数。那么如果你用一个负数调用sum/1,你会得到一个function_clause错误,你会在以下情况下得到这个错误:在评估函数调用时没有找到匹配的函数子句。当然,你还可以定义另一个处理负数的函数子句。
【讨论】:
使用尾递归 这是下面的代码:
% function entry
sum(N) -> sum(N,0);
sum(0,Acc) -> Acc;
sum(N,Acc) -> sum(N-1,Acc+N).
【讨论】:
使用 Erlang 函数的简单一行示例:
sum(N) -> lists:sum(lists:seq(1, N)).
【讨论】: