我正在试图为没有参数的函数实现定期记忆。为什么这些值重置为0?
let mutable superVersion = 1
type Memoize() =
member this.m f =
let cache = ref 0
let version = ref 0
let returnValue() =
if !version = superVersion then
!cache
else
System.Console.WriteLine(!cache)
cache := f()
System.Console.WriteLine(!cache)
version := superVersion
!cache
returnValue()
let simpleFunction() = 10 + 5 // Could be some mutable data here
let aFunction() =
let Mem = new Memoize()
let myFunc() = simpleFunction() + 1
Mem.m myFunc
这个想法很简单。当数据进入这个程序时,superVersion增加1.这样,所有的函数都必须重新计算,但是只有当新的数据进入时。之后很多后面的函数可以建立在早期的函数上,并且不会重新计算以前的函数。这样,没有必要的事件。
现在我非常新的编程,特别是F#。所以我不知道,将这些函数堆叠在一起会导致堆栈溢出或其他问题?
我想要做的就是数据研究,而不必担心使用事件或事物以正确的顺序计算事物。有点像excel除了excel更进一步,只有当链接中的前一个单元格(依赖关系)发生变化时才计算。
所以我希望能得到关于这个问题的一些信息。然而,现在到主要问题:
当我然后调用函数(),版本和缓存得到计算,然后重置为0.您可以看到我已经放置了2个控制台writelines。第一个值是0,第二个是16.再次调用函数(不改变superVersion),我得到完全相同的结果,而不是在两个都得到16。为什么高速缓存重置为0?
非常感谢。
编辑:就像我选择让我知道答案,我真的忘了什么功能做。他们在使用时称他们的身体。所以一切都在他们重置。我太专注于他们应该实施课程的地方。
为我想要做会去这样的事情是什么的正确实施:
type Cell(f) =
let mem = Memoize()
let _Value() = mem.m f
member this.Value = _Value()
现在,每一个功能,或者我打电话,现在,细胞。我只是创建一个新的单元格实例,并通过我想要的计算(一个函数)。现在因为我在一个类中,Memoize()只创建一次,其状态被保存。使用新的执行Memoize在约翰帕尔默的答案中看到。然而我改变了我最初选择的可变参考。我认为这样更有效率。
噢人,我很尴尬。这个代码在某处非常愚蠢。我只知道它,也可能是这个想法:P – Dimension 2013-03-15 02:09:55
您现在使用的更新版本是“Lazy <'t>”的几乎精确克隆 - 请参阅http://msdn.microsoft.com/zh-cn/library/dd233247。 aspx – 2013-03-15 20:41:27
这个问题的关键在于能够更改版本并使其重新计算,因为新数据进入并因此使所有内容无效。我不明白懒惰是怎么可能的。它在你所包含的链接中说:“强制执行只执行一次,随后对Force的调用返回相同的结果,但不执行任何代码。” - 但是,谢谢你的信息,这很有趣,我不知道! – Dimension 2013-03-16 00:28:33