开发者

Caching function result f#

I have a function which is constant to its argument, for example

let is_prime x = (test)

But it's pretty large and slow. So I want the result of it to be calculated only once while I'm calling it as often as I want.

I've tried to do it in a way I did it in not functional languages:

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

But I think I'm deeply wrong. Caching such result must be something very 开发者_如何学JAVAcommon and simple for functional languages.


Here is the Internet Archive link.


I'm having trouble testing this in FSI, but it should be fine in a normal F# project.

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

Its signature is ('a->'b) -> ('a->'b) when 'a : equality. It takes non-curried function and returns another with an identical signature. The function given is only called once for each unique argument that is passed to it. This makes it good for expensive pure functions. This cache function however is not pure, and not thread-safe. Here's an example of its usage:

let slow n = // 'a -> 'a
    System.Threading.Thread.Sleep(1000)
    n

let fast = cache slow // 'a -> 'a

Calling fast 1 will cause a second of sleep the first time you call it. Each successive call with the same parameter will return the value instantly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜