There are two ways of combining the functional and object-oriented paradigm. To some extent, they are independent and you can write immutable (functional) code that is structured using types (written as F# objects). An F# example of Client
type written like this would be:
// Functional 'Client' class
type Client(name, income) =
// Memebers are immutable
member x.Name = name
member x.Income = income
// Returns a new instance
member x.WithIncome(ninc) =
new Client(name, ninc)
member x.Report() =
printfn "%s %d" name income
Note that the WithIncome
method (which "changes" the income of the client) doesn't actually do any modifications - it follows the functional style and creates a new, updated, client and returns it as the result.
On the other hand, in F# you can also write object-oriented code that has mutable public properties, but uses some immutable data structure under the cover. This may be useful when you have some nice functional code and want to expose it to C# programmers in a traditional (imperative/object-oriented) way:
type ClientList() =
// The list itself is immutable, but the private
// field of the ClientList type can change
let mutable clients = []
// Imperative object-oriented method
member x.Add(name, income) =
clients <- (new Client(name, income))::clients
// Purely functional - filtering of clients
member x.Filter f =
clients |> List.filter f
(The example is taken from the source code of Chapter 9 of my book. There are some more examples of immutable object-oriented code, for example in parallel simulation in Chapter 14).