Reputation: 146
I'm trying to implement a settings module in my app which should contain information about current state of application. For example, if the user opens some file I need to store the file name. Since I'm still learning F# I want to do it as functional a possible.
I know I should create a new value everytime I change something, but where do I store this value? It should be a singleton and since it's immutable I struggle with the solution.
How do I implement such "global variable"? Does it even play well within functional approach?
Upvotes: 0
Views: 247
Reputation: 47914
You can store a global variable in a module:
module Settings =
let mutable FileName = ""
open Settings
FileName <- "foo"
Upvotes: 0
Reputation: 6223
This works just as it would within a function, with let mutable
(used inside a module):
let mutable a = 4
a // gets a
a <- 6 // sets a
Or, you could use a mutable object as a static member (this example uses a mutable reference cell):
type Settings =
static member Filename = ref ""
Settings.Filename := "OpenMe.txt"
Global variables may be necessary sometimes, and this could be a viable use case, but they are considered dangerous. Values that change and influence a large portion of the program can make things rather unpredictable.
That said, in cases like yours, a single global variable can be a good solution. It could hold a record with the individual settings. I'd pay attention that any operations changing the global variable happen only when the program is in a well-defined state (i.e. not in the middle of a complicated operation) and guarantee that the variable's new value is sound.
Example:
type StateVariables =
{ Filename : string
Opened : int }
module State =
let mutable private cur = { Filename = ""; Opened = 0 }
let get () = cur
let openFile name =
// ...
cur <- { cur with Filename = name; Opened = cur.Opened + 1 }
Upvotes: 2