评估Erlang递归函数(为什么这个工作)
我开始学习一些Erlang,现在我陷入了“问题”的困境。
我知道递归如何工作,我知道HigherOrderFunctions的基础知识。
因此,为了更深入地理解我实现“lists:all / 2”的整个概念,并使用fold自己:
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),当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?
基本上,对于最后一次调用你是正确的,但是在进行分析时,你已经用Start
值代替true
,实际上这个值是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
,这是错误的。
尽量避免针对简单问题的复杂解决方案(代码紧凑是函数式语言的好处之一):
all(_, []) ->
true;
all(Pred, [H|T]) ->
case Pred(H) of
true ->
all(Pred, T);
false ->
false
end.
链接地址: http://www.djcxy.com/p/66283.html
上一篇: Evaluation of Erlang recursive function (why does this work)