3

我开始学习一些 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”的所有返回使用逻辑与?

4

2 回答 2

4

基本上,您对最后一次通话是正确的,但是在进行分析时,您已经替换trueStartvalue,实际上这个 value 是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

因为 in last callPred是 true,而你正在返回ToF,这是 false。

于 2012-09-21T10:18:10.417 回答
2

尽量避免简单问题的复杂解决方案(代码紧凑性是函数式语言的好处之一):

all(_, []) ->
   true;
all(Pred, [H|T]) ->
   case Pred(H) of
      true ->
         all(Pred, T);
      false ->
         false
   end.
于 2012-09-21T10:30:06.113 回答