7 people like it.
Like the snippet!
memoizeBy
Sometimes you might wish to memoize a function whose input doesn't have the equality and comparison constraints, or maybe the comparison of your given type is just too slow for what you need. To fix this, you simply provide a function which converts the input into something more fitting as an extra parameter.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
|
// Note that Dictionary lookups are to be much faster than F#'s map and so should
// be used when writing library code.
let memoizeBy inputToKey f =
let cache = Dictionary<_, _>()
fun x ->
let k = inputToKey x
if cache.ContainsKey(k) then cache.[k]
else let res = f x
cache.[k] <- res
res
// Example:
/// Caches calls to Type.GetGenericArguments
let cachedGetGenericArguments =
let inputToKey (vType: System.Type) = vType.FullName
let genericArgumentGetter (vType: System.Type) =
Type.GetGenericArguments().[0]
memoizeBy inputToKey genericArgumentGetter
|
val memoizeBy : inputToKey:('a -> 'b) -> f:('a -> 'c) -> ('a -> 'c)
Full name: Script.memoizeBy
val inputToKey : ('a -> 'b)
val f : ('a -> 'c)
val cache : obj
val x : 'a
val k : 'b
val res : 'c
val cachedGetGenericArguments : (System.Type -> obj)
Full name: Script.cachedGetGenericArguments
Caches calls to Type.GetGenericArguments
val inputToKey : (System.Type -> string)
val vType : System.Type
namespace System
type Type =
inherit MemberInfo
member Assembly : Assembly
member AssemblyQualifiedName : string
member Attributes : TypeAttributes
member BaseType : Type
member ContainsGenericParameters : bool
member DeclaringMethod : MethodBase
member DeclaringType : Type
member Equals : o:obj -> bool + 1 overload
member FindInterfaces : filter:TypeFilter * filterCriteria:obj -> Type[]
member FindMembers : memberType:MemberTypes * bindingAttr:BindingFlags * filter:MemberFilter * filterCriteria:obj -> MemberInfo[]
...
Full name: System.Type
property System.Type.FullName: string
val genericArgumentGetter : (System.Type -> 'a)
More information