Vlad
Vlad

Reputation: 146

How to implement application wide variables

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

Answers (2)

Daniel
Daniel

Reputation: 47914

You can store a global variable in a module:

module Settings =
    let mutable FileName = ""

open Settings

FileName <- "foo"

Upvotes: 0

Vandroiy
Vandroiy

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

Related Questions