I need a global variable (I could build it, then pass it to every single function call and let every single function call know about it, but that seems just as hacky, less readable and more work). The global variables are lookup tables (endgame: opening book and transpositions/cache) for a game.
That some of the code may lose its idempotent behavior is actually the point (speedups). I know global mutable state is bad but it's worth it (10x+ performance improvement). So how do I build a singleton or use a static value in a static class with combinators?
They are effectively identical but I am curious what people have done on this sort of problem. Or should I be passing the thing around to everyone (or at least a reference)?
here is the convention used in F# PowerPack Matrix library (\src\FSharp.PowerPackmath\associations.fs
):
// put global variable in a special module
module GlobalAssociations =
// global variable ht
let ht =
let ht = new System.Collections.Generic.Dictionary<Type,obj>()
let optab =
[ typeof<float>, (Some(FloatNumerics :> INumeric<float>) :> obj);
typeof<int32>, (Some(Int32Numerics :> INumeric<int32>) :> obj);
...
typeof<bignum>, (Some(BigRationalNumerics :> INumeric<bignum>) :> obj); ]
List.iter (fun (ty,ops) -> ht.Add(ty,ops)) optab;
ht
// method to update ht
let Put (ty: System.Type, d : obj) =
// lock it before changing
lock ht (fun () ->
if ht.ContainsKey(ty) then invalidArg "ty" ("the type "+ty.Name+" already has a registered numeric association");
ht.Add(ty, d))