【问题标题】:Evaluation of Erlang recursive function (why does this work)Erlang 递归函数的评估(为什么会这样)
【发布时间】:2012-09-13 17:38:37
【问题描述】:

我开始学习一些 Erlang,现在我被以下“问题”困住了。

我知道递归的工作原理,并且了解 HigherOrderFunctions 的基础知识。

所以为了更深入地了解整个概念,我自己使用 fold 实现了“lists: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 设置为“fun(X) when X == 3 -> true; (_) -> false end”时,它显然返回“false”。但为什么?如果我在返回某些东西之前将其作为最后一次电话在纸上完成,我会得到:

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

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

所以当我做对了,最后一次调用应该是 fold(_, true, []) 并且应该返回 "true" 而它没有返回。

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

【问题讨论】:

  • 你的预测可能很有趣(X) -> X == 3 end

标签: recursion erlang evaluation


【解决方案1】:

基本上,最后一次调用是正确的,但是在进行分析时,您已将 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 为假。

【讨论】:

  • 天哪,谢谢你,我知道我的想法一定有错误;)
【解决方案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.

【讨论】:

  • 我知道,如果不仅仅是为了更深入地了解 HighOrderFunctions 的整个概念,我也不会像这样编写它,我想看看我是否可以让它与 fold/3 一起使用它说几乎所有关于列表的问题都可以通过使用 fold/3 来解决。无论如何谢谢:)
  • @abdrl:您的函数完全符合其名称的含义。只有当列表 L 的 所有 元素被 Pred 函数评估为 true 时,它​​才返回 true,在所有其他情况下返回 false。
猜你喜欢
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多