在Erlang过度使用警卫?

dag*_*da1 4 erlang

我有以下函数,它取一个像5这样的数字,并创建一个从1到该数字的所有数字的列表,因此create(5).返回[1,2,3,4,5].

我认为我已经过度使用了警卫,并且想知道是否有更好的方法来编写以下内容:

create(N) ->
    create(1, N).

create(N,M) when N =:= M ->
    [N];
create(N,M) when N < M ->
    [N] ++ create(N + 1, M).
Run Code Online (Sandbox Code Playgroud)

Tad*_*mas 6

守卫N < M可能很有用.一般来说,你不需要保护平等; 你可以使用模式匹配.

create(N) -> create(1, N).

create(M, M) -> [M];
create(N, M) when N < M -> [N | create(N + 1, M)].
Run Code Online (Sandbox Code Playgroud)

你通常也想编写函数,因此它们是尾递归的,其中通常的习惯用法是写入头部然后在结尾处反转.

create(N) -> create(1, N, []).

create(M, M, Acc) -> lists:reverse([M | Acc]);
create(N, M, Acc) when N < M -> create(N + 1, M, [N | Acc]).
Run Code Online (Sandbox Code Playgroud)

(当然,通过这个具体的例子,你可以选择以相反的顺序构建结果,而不是最多M,这将使得lists:reverse调用变得不必要.)

如果create/2(或create/3)没有出口并且你打开适当的防守create/1,那么额外的N < M防守可能会有些过分.我通常只检查导出的函数并信任我自己的内部函数.