我正在寻找一种方法来记住OCaml函数f
的结果,该函数需要两个参数(或更多,一般来说)。此外(这是困难的部分),如果两个参数的任何一个值被垃圾回收,我希望这个过程背后的映射完全忘记结果。
对于只接受一个参数的函数,可以使用Weak
模块及其Make
函子以简单的方式完成此操作。为了将其推广到可以记住更高arity函数的东西,一个朴素的解决方案是创建一个从值元组到结果值的弱映射。但是这对于垃圾回收来说无法正常工作,因为值元组仅存在于记忆函数的范围内,而不存在调用f
的客户端代码。事实上,弱引用将是元组,它将在记忆后立即被垃圾回收(在最坏的情况下)。
有没有办法在不重新实现Weak.Make
的情况下做到这一点?
哈希与我的要求正交,事实上,对于我的价值观来说并不是真正可取的。
谢谢!
您可以有一个树结构,而不是按元组进行索引。 您将有一个弱表,该表由第一个函数参数索引,该函数参数的条目是辅助弱表。 辅助表将由第二个函数参数编制索引,并包含记忆结果。 一旦任一函数参数被 GCed,此结构就会忘记记忆函数结果。 但是,只要第一个函数参数处于活动状态,辅助表本身就会保留。 根据函数结果的大小和不同第一个参数的分布,这可能是一个合理的权衡。
我也没有测试过这个。 而且这似乎也相当明显。
一个想法是执行自己的垃圾回收。
为简单起见,我们假设所有参数都具有相同的类型k
。
除了包含由k * k
键键的记忆结果的主弱表之外,还创建一个包含 k
类型单个参数的辅助弱表。这个想法是偶尔扫描主表并删除不再需要的绑定。这是通过在辅助表中查找参数来完成的;然后,如果其中任何一个消失了,则从主表中删除绑定。
(免责声明:我还没有测试过这个;它可能不起作用,或者可能有更好的解决方案)
这是一个老问题,但我的同事最近开发了一个名为Adapton的增量计算库,可以处理此功能。您可以在此处找到代码。您可能想使用 LazySABidi 函子(其他函子用于基准测试)。您可以在"应用程序"文件夹中查看有关如何使用该库的示例。如果您还有其他问题,请告诉我。