【发布时间】:2021-01-30 09:02:44
【问题描述】:
我必须完成一个练习
我写了一个函数 memo : (('a -> 'b) -> 'a -> 'b) -> stats -> 'a -> 'b. 函数 memo 需要作为输入一个函数 f(我们想要记忆的函数),一个类型统计的记录(它的类型声明在下面给出)来跟踪我们访问本地存储的频率和我们添加了多少条目,并返回一个函数输入'a -> 'b。
当使用 'a 类型的输入调用此函数时,它将运行 f,记忆中间结果,并作为最终结果返回 'b 类型的值。它还将相应地更新其统计记录中的值。例如,要创建一个将数字相加到 x 的记忆函数,我们有 memo (fun g x -> if x=0 then 0 else x + g(x-1)) stats
记录类型统计有两个字段:
entries:已记忆的结果数
lkp:在 store 中找到 memoized 结果而不是执行函数的次数
注意给定函数 f 的类型:它本身需要另一个函数作为参数。具体来说,传递给 f 的函数 g 将是 f 将在其递归情况下调用的函数。
我遇到的问题是我的查找次数总是减少 1 或 2。如果有人能澄清为什么会发生这种情况或给我一个提示,我将不胜感激。下面是我的尝试,它计算函数调用的正确值和正确的条目数。希望下面的代码能让它更清晰:
type stats =
{ entries : int ref;
lkp : int ref }
let memo (f: (('a -> 'b) -> 'a -> 'b)) (stats: stats) : ('a -> 'b) =
let map = Hashtbl.create 1000 in
let rec g x =
match Hashtbl.find_opt map x with
| None -> let result = f (g) x in Hashtbl.add map x result ; stats.entries := !(stats.entries) + 1 ; result
| Some v -> stats.lkp := !(stats.lkp)+ 1 ; v
in stats.entries := !(stats.entries) + 1 ; f g
【问题讨论】:
-
请不要以使现有答案无效的方式修改问题。
标签: reference ocaml memoization