在遞迴函式中進行記憶

使用前面計算整數的階乘的示例,在雜湊表中放入在遞迴內計算的所有階乘的值,這些值不會出現在表中。

由於有關的文章在記憶化 ,我們定義一個函式 f 接受一個函式引數 fact 和整數引數。此函式 f 包含從 fact(n-1) 計算 n 的階乘的指令。

這允許通過 memorec 而不是 fact 本身返回的函式來處理遞迴,並且如果 fact(n-1) 值已經被計算並且位於雜湊表中,則可能停止計算。

let memorec f =
   let cache = Dictionary<_,_>()
   let rec frec n = 
       let value = ref 0
       let exist = cache.TryGetValue(n, value)
       match exist with
       | true -> 
           printfn "%O -> In cache" n
       | false ->
           printfn "%O -> Not in cache, calling function..." n
           value := f frec n
           cache.Add(n, !value)
       !value
   in frec

let f = fun fact n -> if n<2 then 1 else n*fact(n-1)

[<EntryPoint>]
let main argv = 
    let g = memorec(f)
    printfn "%A" (g 10)
    printfn "%A" "---------------------"
    printfn "%A" (g 5)
    Console.ReadLine()
    0

結果:

10 -> Not in cache, calling function...
9 -> Not in cache, calling function...
8 -> Not in cache, calling function...
7 -> Not in cache, calling function...
6 -> Not in cache, calling function...
5 -> Not in cache, calling function...
4 -> Not in cache, calling function...
3 -> Not in cache, calling function...
2 -> Not in cache, calling function...
1 -> Not in cache, calling function...
3628800
"---------------------"
5 -> In cache
120