4 people like it.

Memoize Async Function

Cache a function's asynchronously-computed result for each argument to reduce expensive and repetitive computation of an asynchronous operation. Uses a concurrent dictionary for backing storage, and at-least-once invocation semantics per key.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
    let inline memoize f =
        let dict = System.Collections.Concurrent.ConcurrentDictionary()
        fun x -> async {
            match dict.TryGetValue x with
            | true, result -> return result
            | false, _ ->
                let! result = f x
                dict.TryAdd(x, result) |> ignore
                return result
        }
val memoize : f:('a -> Async<'b>) -> ('a -> Async<'b>)

Full name: Script.memoize
val f : ('a -> Async<'b>)
val dict : System.Collections.Concurrent.ConcurrentDictionary<'a,'b>
namespace System
namespace System.Collections
namespace System.Collections.Concurrent
Multiple items
type ConcurrentDictionary<'TKey,'TValue> =
  new : unit -> ConcurrentDictionary<'TKey, 'TValue> + 6 overloads
  member AddOrUpdate : key:'TKey * addValueFactory:Func<'TKey, 'TValue> * updateValueFactory:Func<'TKey, 'TValue, 'TValue> -> 'TValue + 1 overload
  member Clear : unit -> unit
  member ContainsKey : key:'TKey -> bool
  member Count : int
  member GetEnumerator : unit -> IEnumerator<KeyValuePair<'TKey, 'TValue>>
  member GetOrAdd : key:'TKey * valueFactory:Func<'TKey, 'TValue> -> 'TValue + 1 overload
  member IsEmpty : bool
  member Item : 'TKey -> 'TValue with get, set
  member Keys : ICollection<'TKey>
  ...

Full name: System.Collections.Concurrent.ConcurrentDictionary<_,_>

--------------------
System.Collections.Concurrent.ConcurrentDictionary() : unit
System.Collections.Concurrent.ConcurrentDictionary(collection: System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<'TKey,'TValue>>) : unit
System.Collections.Concurrent.ConcurrentDictionary(comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Concurrent.ConcurrentDictionary(concurrencyLevel: int, capacity: int) : unit
System.Collections.Concurrent.ConcurrentDictionary(collection: System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<'TKey,'TValue>>, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Concurrent.ConcurrentDictionary(concurrencyLevel: int, collection: System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<'TKey,'TValue>>, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Concurrent.ConcurrentDictionary(concurrencyLevel: int, capacity: int, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
val x : 'a
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
System.Collections.Concurrent.ConcurrentDictionary.TryGetValue(key: 'a, value: byref<'b>) : bool
val result : 'b
System.Collections.Concurrent.ConcurrentDictionary.TryAdd(key: 'a, value: 'b) : bool
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
Raw view Test code New version

More information

Link:http://fssnip.net/qp
Posted:8 years ago
Author:Jonathan Leaver
Tags: memoize async concurrent function