Erlang 代码评论
我正在尝试了解一些基本的 erlang 功能,并且我可以对以下内容进行一些评论。
我有以下 erlang 代码,它接受一个元组列表,如果找到一个键,则返回一个减去元素的列表:
delete(Key, Database) ->
remove(Database, Key, []).
remove([], Key, Acc) ->
Acc;
remove([H|T], Key, Acc) ->
if
element(1, H) /= Key ->
[H| remove(T, Key, Acc)];
true ->
remove(T, Key, Acc)
end.
这是这样做的好方法吗?
if 语句似乎不正确。
我对累加器 Acc 的使用是否使这个尾部递归?
I am trying to get my head round some basic erlang functionality and I could do with some comments on the following.
I have the following erlang code that takes a list of tuples and returns a list minus an element if a key is found:
delete(Key, Database) ->
remove(Database, Key, []).
remove([], Key, Acc) ->
Acc;
remove([H|T], Key, Acc) ->
if
element(1, H) /= Key ->
[H| remove(T, Key, Acc)];
true ->
remove(T, Key, Acc)
end.
Is this a good way of doing this?
The if statement seems incorrect.
Also is my use of the accumulator Acc making this tail recursive?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,您对
Acc
的使用不会使其成为尾递归。你的 if 分支返回[H| remove(T, Key, Acc)]
这不是尾调用,并且大多数时间都会使用此分支。更准确地说,您对Acc
的使用是无用的,因为它始终是[]
,您根本不会更改它的值。正确的代码应该是这样的。但如果你的列表成员总是成对的,我更喜欢直接模式匹配:
但我认为这是可以应用 神话:尾递归函数比递归函数快得多,所以我会使用更简单的递归版本:
No, your usage of
Acc
doesn't make it tail recursive. Your branch of if returns[H| remove(T, Key, Acc)]
which is not tail call and this branch would be used most of time. To be more precise your usage ofAcc
is useless because it would be[]
whole time, you don't change its value at all. Correct code should look like.But if your list members are always pairs I would prefer direct pattern match:
But I think this is example where can apply Myth: Tail-recursive functions are MUCH faster than recursive functions so I would use much simpler recursive version:
如前所述,有一个标准模块函数已经可以执行此操作(proplists:delete)。不需要多说,但是......
我倾向于保留原始方法名称(删除),但有一个本地版本,包括累加器作为参数。上下文让我认为“数据库”中元组的顺序并不重要,因此列表:反向是不必要的。
这里有一些事情:
As mentioned, there is a standard module function that already does this (proplists:delete). Shouldn't need to say more, but...
I'd tend to keep the original method name (delete), but have a local version including the accumulator as parameter. The context makes me think the order of the tuples in the "database" doesn't matter, so that a lists:reverse isn't necessary.
A couple things here: