wmeyer 的解释非常好。我只想添加一个可能有用的“可视化”-->
首先,我用的是书的原版(PDF),我相信,功能是这样的 -->
declare Pascal AddList ShiftLeft ShiftRight
fun {Pascal N}
if N==1 then [1]
else
{AddList {ShiftLeft {Pascal N-1}} {ShiftRight {Pascal N-1}}}
end
end
fun {ShiftLeft L}
case L of H|T then
H|{ShiftLeft T}
else [0] end
end
fun {ShiftRight L} 0|L end
fun {AddList L1 L2}
case L1 of H1|T1 then
case L2 of H2|T2 then
H1+H2|{AddList T1 T2}
end
else nil end
end
假设您想查看帕斯卡三角形的第 8 行。你要输入:
{Browse {Pascal 8}}
即您想显示将 8 输入到书中/此处定义的函数 Pascal 的结果。
首先,函数测试它刚刚传递的值是否为 1(直到递归的最后一次迭代(或最终的递归调用)才会为真,此时 [1](来自如果 N==1) 将作为 THAT CALL OF Pascal 的输出返回,并将(Pascal 的)执行“链”传递回最先调用的下一个最近的调用(其中结果 [1] 被添加到匹配 ShiftLeft 或 ShiftRight 的结果,然后该结果被发送回链上,一直循环,直到到达第一个(Pascal 8)。所以调用深入 8 级,然后将答案向上传递这些级别,直到你得到最终答案......但我已经跳到前面了。
好的,由于您输入了 8,因此测试 N==1 失败,因此不能立即移动“列表”并将它们添加到 else 子句中,函数无法做到这一点“方程式”中有未定义的术语说“我会尝试 N - 1!也许这将是最终答案!” (对于 ShiftLeft 和 ShiftRight - 所以每次递归发生时都会发生这种分支)
因此,该函数在 ShiftLeft 和 ShiftRight 中等待来自 Pascal N-1 的答案...等待,等待...
好吧,对于 N==1,{Pascal 7} 也不成立,因此 Pascal 的新调用(“调用”、第二和第三调用,左右!)也会问“什么是 Pascal N - 1"(这次是 7-1),他们都会等待答案......
这样一直持续下去……哦等等,直到 N==1!
然后 [1],一个列表,被返回 BACK UP THE CHAIN...所以,每个连续的等待函数调用,最近的第一个(记住所有这些在到达这里的路上越来越多地发生'bottom' 其中 N==1 随着拆分的增加(每次调用一次调用 ShiftLeft 和 ShiftRight))最终可以使用它一直在等待的答案进行 AddList 计算,从它自己的个人私人调用 ShiftLeft 和 ShiftRight .
一切都一直到底部,分解成越来越多的函数调用,然后我们回到顶部,最后可以得到一个返回的答案。最后的答案是第一次调用 Pascal 函数 {Pascal 8} 的 else 子句,现在在内部(因为 Pascal 三角形的第 8 行是 [1 7 21 35 35 21 7 1])将如下所示:
{AddList [1 7 21 35 35 21 7 0] [0 7 21 35 35 21 7 1]}
添加后的列表作为最终答案返回并显示:[1 7 21 35 35 21 7 1]