我有一个与其参数不变的函数,例如
let is_prime x = (test)
但它很大而且很慢。所以我希望它的结果只计算一次,而我会按照自己的意愿调用它。
我试图以非功能性语言的方式做到这一点:
let _is_prime x = (test)
let mutable _is_prime_primes = []
let mutable _is_prime_tested = []
let is_prime x =
if List.exists (fun el -> el = x) _is_prime_primes then
true
else
if List.exists (fun el -> el = x) _is_prime_tested then
false
else
let result = _is_prime x
if result then _is_prime_primes <- x :: _is_prime_primes
_is_prime_tested <- x :: _is_prime_tested
result
但我认为我深深地错了。对于函数式语言来说,缓存这样的结果必须是非常常见和简单的事情。
答案 0 :(得分:3)
这是关于这个主题的thorough thread。
这是Internet Archive链接。
答案 1 :(得分:1)
我在FSI中测试时遇到了麻烦,但在正常的F#项目中应该没问题。
let cache f =
let dict = new Dictionary<_,_>()
fun n ->
if dict.ContainsKey(n) then dict.[n]
else
let r = f n
dict.[n] <- r
r
它的签名是('a->'b) -> ('a->'b) when 'a : equality
。它采用非curried函数并返回另一个具有相同签名的函数。给定的函数仅对传递给它的每个唯一参数调用一次。这使它适用于昂贵的纯功能。但是,此缓存功能不是纯粹的,也不是线程安全的。以下是其用法示例:
let slow n = // 'a -> 'a
System.Threading.Thread.Sleep(1000)
n
let fast = cache slow // 'a -> 'a
第一次调用时,调用fast 1
会导致第二次睡眠。每个具有相同参数的连续调用将立即返回值。