我开始学习一些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?
答案 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.