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}}
つまり、本/ここで定義されているように、関数Pascalに8をフィードした結果を表示したいとします。
最初に、関数は渡された値が1であるかどうかをテストします(これは、再帰の最後の反復(または最後の再帰呼び出し)まで真ではありません。その時点で[1](N =の場合から) = 1)は、THAT CALL OF Pascalの出力として返され、(Pascalの)実行の「チェーン」を最初に次の最新の呼び出しに戻します(その結果[1]は、の結果に追加されます。一致するShiftLeftまたはShiftRightを実行すると、その結果がチェーンに送り返され、最初の結果(Pascal 8)に到達するまで何度も繰り返されます。したがって、呼び出しは8レベル深くなり、応答は次のレベルまで返されます。あなたは最終的な答えを得る...しかし私は先にジャンプした。
わかりました。8をフィードしたため、テストN == 1は失敗します。したがって、「リスト」をシフトしてelse句にすぐに追加する代わりに、関数は未定義の用語でそれを行うことができません。 「方程式」では、「N-1を試してみます!それが最終的な答えになるかもしれません!!」と書かれています。(ShiftLeftおよびShiftRightの場合-したがって、この分岐はrecursinoが発生するたびに発生します)
したがって、関数はShiftLeftおよびShiftRight内のPascal N-1からのその応答を待機します...待機中、待機中...
ええと、{Pascal7}はN== 1にも当てはまらないので、Pascalの新しい呼び出し(「呼び出し」、2番目と3番目の呼び出し、左右!)は、両方とも「PascalN-1とは何ですか」と尋ねます。 「(今回は7-1)そして彼らは両方とも答えを待つでしょう...
これは何度も何度も繰り返されます....ああ、N == 1になるまで待ってください!
次に、リストである[1]が返されます。BACKUP THE CHAIN ...したがって、連続する待機中の関数呼び出しは、最新のものが最初に返されます(これらはすべて、「最下部」に到達するまでの途中でますます発生することに注意してください。ここで、分割が増えるにつれてN == 1(各呼び出しで一度にShiftLeftとShiftRightを呼び出すことにより)、ShiftLeftとShiftRightへの独自のプライベート呼び出しから待機していた回答を使用して最終的にAddList計算を行うことができます。
すべてが一番下まで行き、ますます多くの関数呼び出しに分割され、次に一番上に戻って、最終的に答えを返すことができます。その最終的な答えは、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つのリストです:[1 7 21 35 35 21 7 1]