私が行っている関数型プログラミング コースの現在の課題では、特定の関数のメモ化されたバージョンを作成する必要があります。メモ化を説明するために、次の例を示します。
fiblist = [ fibm x | x <- [0..]]
fibm 0 = 0
fibm 1 = 1
fibm n = fiblist !! (n-1) + fiblist !! (n-2)
しかし、私はこれがどのように機能するかを完全には理解していません。
に電話しましょうfibm 3
。
fibm 3
--> fiblist !! 2 + fibList 1
--> [fibm 0, fibm 1, fibm 2] !! 2 + [fibm 0, fibm 1] !! 1
--> fibm 2 + fibm 1
--> (fiblist !! 1 + fiblist 0) + 1
--> ([fibm 0, fibm 1] !! 1 + [fibm 0] !! 0) + 1
--> (fibm 1 + fibm 0) + 1
--> 1 + 0 + 1
--> 2
他の質問/回答とグーグルから、どういうわけか、評価されたフィブリストが呼び出し間で共有されることがわかりました。
これは、たとえば の場合fiblist !! 2 + fiblist !! 1
、リストの値は に対して 1 回だけ計算されfiblist !! 2
、その後 で再利用されるということfiblist !! 1
ですか?
次に、2 つのフィボナッチ数は呼び出しごとに 1 回だけ計算されるため、呼び出しの指数関数的な数はありません。fiblist
しかし、関数内の呼び出しの「下位」レベルはどうでしょうか? fiblist
元のfibm
呼び出しで計算されたものからどのようなメリットがありますか?