我正在尝试记忆一个类的成员函数,但是每次(由另一个成员)调用该成员时,它都会创建一个全新的缓存和“记忆”函数。
member x.internal_dec_rates =
let cache = new Dictionary< Basis*(DateTime option), float*float>()
fun (basis:Basis) (tl:DateTime option) ->
match cache.TryGetValue((basis,tl)) with
| true, (sgl_mux, sgl_lps) -> (sgl_mux, sgl_lps)
| _ ->
let (sgl_mux, sgl_lps) =
(* Bunch of stuff *)
cache.Add((basis,tl),(sgl_mux,sgl_lps))
sgl_mux,sgl_lps
我使用“真实世界函数式编程”中的清单 10.5 作为模型。我试过使用记忆高阶函数,但没有帮助。上面的清单直接内置了 memoization。
问题是,当我称之为例如
member x.px (basis:Basis) (tl: DateTime option) =
let (q,l) = (x.internal_dec_rates basis tl)
let (q2,l2) = (x.internal_dec_rates basis tl)
(exp -q)*(1.-l)
执行到 'let cache=...' 行,完全失败了。我放入 (q2,l2) 行以确保它不是范围问题,但似乎不是。
事实上,我使用 Petricek 的代码作为成员函数进行了测试,这似乎有同样的问题:
// Not a member function
let memo1 f =
let cache = new Dictionary<_,_>()
(fun x ->
match cache.TryGetValue(x) with
| true, v -> v
| _ -> let v = f x
cache.Add(x,v)
v
)
member x.factorial = memo1(fun y->
if (y<=0) then 1 else y*x.factorial(y-1))
甚至 x.factorial 的内部递归似乎也为每个级别设置了一个新的“缓存”。
我做错了什么,我怎样才能做到这一点?