Classes, Properties and Methods

type BankAccount(owner: string, initialBalance: decimal) =    // primary constructor
    let mutable balance = initialBalance                       // private field
    let history = ResizeArray<string>()
    do if initialBalance < 0m then invalidArg (nameof initialBalance) "Must be non-negative"

    new(owner) = BankAccount(owner, 0m)                        // secondary constructor

    member _.Owner = owner                                     // read-only property
    member _.Balance = balance
    member val Nickname = "" with get, set                     // auto-property
    member _.History = history |> Seq.toList

    member this.Deposit(amount: decimal) =
        if amount <= 0m then invalidArg (nameof amount) "Must be positive"
        balance <- balance + amount
        history.Add $"Deposit {amount}"
        this                                                   // fluent

    member _.Withdraw(amount: decimal) =
        if amount > balance then Error "Insufficient funds"
        else
            balance <- balance - amount
            history.Add $"Withdraw {amount}"
            Ok balance

    member _.Item with get (i: int) = history[i]               // indexer: acct
…