评估Erlang递归函数(为什么这样做)

时间:2012-09-21 09:47:33

标签: recursion erlang evaluation

我开始学习一些Erlang,现在我遇到了“问题”。

我知道递归是如何工作的,我知道HigherOrderFunctions的基础知识。

因此,为了更多地了解整个概念,我使用fold自己实现了“list:all / 2”:

fold(_, Start, []) -> Start;
fold(F, Start, [H|T]) -> fold(F, F(H, Start), T).

all(Pred, L) ->
    F = fun(H, ToF) ->
        case Pred(H) of
            true -> ToF;
            false -> false
        end
    end,
    fold(F, true, L).

我知道这个版本并不关心空列表,但这并不困扰我。我无法弄清楚它为什么会起作用。

当我使用我的列表[1,2,3]并将Pred设置为“有趣(X)时X == 3 - > true;(_) - > false end”它显然返回“false” 。但为什么?如果我在最后一次电话会议之前通过纸张处理这件事,我会得到:

fold(F, F(H, Start), T)

其中F是Pred而F(H,Start)返回“true”,因为最后一个元素是3而T是一个空列表[]。

所以当我说得对,最后一次调用应该是fold(_,true,[]),因此应该返回“true”,而不是。

我在这里遗漏了什么,或者在评估最后一个表达时我有什么不对吗?这个函数是否以某种方式对“Pred”的所有返回使用逻辑AND?

2 个答案:

答案 0 :(得分:4)

基本上,您对最后一次调用是对的,但在进行分析时,您已将true替换为Start值,实际上此值为false

fold(F, true, [1,2,3])

评估为:

fold(F, true, [1|[2,3]]) -> fold(F, F(1, true), [2,3])

反过来评估为:

fold(F, false, [2|3]) -> fold(F, F(2, false) [3])

反过来评估为:

fold(F, false, [3|[]]]) -> fold(F, F(3, false), [])

评估为:

fold(_, false, []) -> false

因为在上次通话中Pred是真的,而您正在返回ToF,这是假的。

答案 1 :(得分:2)

Try to avoid complex solutions for simple problems(代码紧凑性是函数式语言的一个优点):

all(_, []) ->
   true;
all(Pred, [H|T]) ->
   case Pred(H) of
      true ->
         all(Pred, T);
      false ->
         false
   end.