Style Guides for Global Variables in F #

For the project I'm working on, I need a global variable (technically I don’t do this, I could create it and then pass it to each function call, and let every function call know about it, but it just seems like a hack, less readable and working.)

Global variables are lookup tables (endgame, open book and transposition / cache) for the game.

The fact that some code may lose some of its unresponsive behavior is actually a point (acceleration), yes, I know that the global volatile state is bad, it really stands in this case (10x + performance improvement)

So here is the question: "build a singleton or use a static value in a static class with combinators"

They are virtually identical, but I'm curious what people did before on this issue.

Or, alternatively, should I pass things on to everyone (or at least link to it anyway), is this really the best answer?

+6
source share
3 answers

this uses the convention used in the 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)) 
+2
source

Here is a solution similar to the solution posted by @Yin Zhu's, but using abstract types to indicate the use interface for the mutable value, a local definition for encapsulating and object literals to provide implementation (this is taken from Expert F #, which is co-authored by don Xime):

 type IPeekPoke = abstract member Peek: unit -> int abstract member Poke: int -> unit let makeCounter initialState = let state = ref initialState { new IPeekPoke with member x.Poke(n) = state := !state + n member x.Peek() = !state } 
+4
source

You can also do this with static fields, for example:

 type Common() = static let mutable queue : CloudQueue = null static let mutable storageAccount : CloudStorageAccount = null static member Queue with get() = queue and set v = queue <- v static member StorageAccount with get() = storageAccount and set v = storageAccount <- v 

In another module, simply:

 open Common Common.Queue <- xxxx 
+3
source

Source: https://habr.com/ru/post/888380/


All Articles