采取
let memoization f =
// The dictionary is used to store values for every parameter that has been seen
let cache = Dictionary<_,_>()
fun c ->
let exist, value = cache.TryGetValue (c)
match exist with
| true ->
// Return the cached result directly, no method call
printfn "%O -> In cache" c
value
| _ ->
// Function call is required first followed by caching the result for next call with the same parameters
printfn "%O -> Not in cache, calling function..." c
let value = f c
cache.Add (c, value)
value
然后
let f (x:array<_>) = x.Length
然后
let g = memoization f
let a = g [|1|]
let b = g [|1|]
我(显然!)希望 b 是已计算的检索到的内存值,但它重新计算了它。
好吧,公平地说,从 C# 的角度来看,这是有道理的,我们又回到了令人讨厌的对象,那么我如何内存一个采用值数组的函数呢?
我注意到列表效果很好 那么数组有什么特别之处呢?
最佳答案
问题是,默认情况下,Dictionary
使用引用相等性来检查对象是否在字典中。这意味着只有当您向其传递相同的数组实例时它才会起作用。下面从缓存中获取值:
let g = memoization f
let arr = [|1|]
let a = g arr
let b = g arr
如果您想根据数组中的值记住结果,可以使用结构相等比较。为此,您所需要做的就是将 HashIdentity.Structural
作为参数传递给 Dictionary
。这使用 F# 库定义的结构比较,为包含相同值的数组返回相同的哈希值:
let cache = Dictionary<_,_>(HashIdentity.Structural)
通过此更改,您原来的示例将按照您的需要运行。
关于f# - 如何从值数组中内存函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71431847/