Home

Built-In Records: Reference Cells

   

Description

To support the concept of getting a reference to the cell memory where a variable is stored, the F# language provides a built-in record named Ref. It is defined in the Microsoft.FSharp.Core namespace. The Ref record supports various operators and is equipped with a property and a field.

We already know that, to declare a variable and get a reference cell where it would be located, we can assign an initial value preceded with the ref keyword. Here is an example:

let price = ref 0.00

To change the value of the variable, you can use the := operator. Another technique is to use the following formula:

(:=) variable-name value

Here is an example:

let price = ref 45.00

// . . .
     
(:=) price 38.75

To get the value of the variable, you can apply the ! operator before the name of the variable. Another technique is to use the following formula:

(!) variable-name

Here are examples:

lopen System
open System.Windows.Forms

// Form: Department Store
let departmentStore = new Form()
departmentStore.Width  <- 265
departmentStore.Height <- 138
departmentStore.Text <- "Department Store"

let price = ref 0.00
let discountRate = ref 0.00
let discountAmount = ref 0.00

// Label: Unit Price
let lblUnitPrice = new Label()
lblUnitPrice.Left   <- 18
lblUnitPrice.Top    <- 19
lblUnitPrice.Width  <- 80
lblUnitPrice.Text   <- "Unit Price:"
departmentStore.Controls.Add lblUnitPrice

// Text Box: Unit Price
let txtUnitPrice = new TextBox()
txtUnitPrice.Left  <- 100
txtUnitPrice.Top   <- 16
txtUnitPrice.Width <- 54
txtUnitPrice.Text   <- "0.00"
departmentStore.Controls.Add txtUnitPrice

// Label: Discount Rate
let lblDiscountRate = new Label()
lblDiscountRate.Left <- 18
lblDiscountRate.Top <- 48
lblDiscountRate.Width <- 80
lblDiscountRate.Text <- "Discount Rate:"
departmentStore.Controls.Add lblDiscountRate

// Text Box: Discount Rate
let txtDiscountRate = new TextBox()
txtDiscountRate.Left  <- 100
txtDiscountRate.Top   <- 43
txtDiscountRate.Width <- 40
txtDiscountRate.Text   <- "0.00"
departmentStore.Controls.Add txtDiscountRate

// Label: Percent
let lblPercent = new Label()
lblPercent.Left <- 140
lblPercent.Top <- 48
lblPercent.Width <- 20
lblPercent.Text <- "%"
departmentStore.Controls.Add lblPercent

// Button: Calculate
let btnCalculate = new Button()
btnCalculate.Left <- 164
btnCalculate.Top  <-  43
btnCalculate.Text <- "Calculate"

// Label: Marked Price
let lblMarkedPrice = new Label()
lblMarkedPrice.Left  <-  18
lblMarkedPrice.Top   <- 78
lblMarkedPrice.Width <-  80
lblMarkedPrice.Text  <- "Marked Price:"
departmentStore.Controls.Add lblMarkedPrice

// Text Box: Marked Price
let txtMarkedPrice = new TextBox()
txtMarkedPrice.Left  <- 100
txtMarkedPrice.Top   <- 75
txtMarkedPrice.Width <- 54
txtMarkedPrice.Text   <- "0.00"
departmentStore.Controls.Add txtMarkedPrice

// Button: Close
let btnClose = new Button()
btnClose.Left <- 164
btnClose.Top  <- 72
btnClose.Text <- "Close"
let btnCloseClick e = departmentStore.Close()
btnClose.Click.Add btnCloseClick
departmentStore.Controls.Add btnClose

let btnCalculateClick e =
    (:=) price (float txtUnitPrice.Text)
    (:=) discountRate (float txtDiscountRate.Text)

    (:=) discountAmount ((!) price * (!) discountRate / 100.00)
    let markedPrice = (!) price - (!) discountAmount

    let strMarkedPrice = sprintf "%0.02f" markedPrice
    txtMarkedPrice.Text <- strMarkedPrice

btnCalculate.Click.Add btnCalculateClick
departmentStore.Controls.Add btnCalculate

do Application.Run departmentStore

Here is an example of testing the program:

Accessing the Labels of a Record

Accessing the Labels of a Record

To support the value of the variable, the Ref record is equipped with a property named Value and a field named contents. Both allow you to get the value of the variable. Here examples of using them

let btnCalculateClick e =
    (:=) price (float txtUnitPrice.Text)
    (:=) discountRate (float txtDiscountRate.Text)

    (:=) discountAmount ((!) price * (!) discountRate / 100.00)
    let markedPrice = price.Value - discountAmount.contents

    let strMarkedPrice = sprintf "%0.02f" markedPrice
    txtMarkedPrice.Text <- strMarkedPrice

The Ref.contents field and the Ref.Value property both also allow you to change the value of the variable. This is done by using the <- operator and the value to assign. This allows you to mix the techniques of mutable variables, classical reference cells, and the Ref record. Here are examples:

open System
open System.Windows.Forms

// Form: Department Store
let departmentStore = new Form()
departmentStore.Width  <- 265
departmentStore.Height <- 138
departmentStore.Text <- "Department Store"

let price          = ref 0.00
let discountRate   = ref 0.00
let discountAmount = ref 0.00
let mutable markedPrice = 0.00

// Label: Unit Price
let lblUnitPrice = new Label()
lblUnitPrice.Left   <- 18
lblUnitPrice.Top    <- 19
lblUnitPrice.Width  <- 80
lblUnitPrice.Text   <- "Unit Price:"
departmentStore.Controls.Add lblUnitPrice

// Text Box: Unit Price
let txtUnitPrice = new TextBox()
txtUnitPrice.Left  <- 100
txtUnitPrice.Top   <- 16
txtUnitPrice.Width <- 54
txtUnitPrice.Text   <- "0.00"
departmentStore.Controls.Add txtUnitPrice

// Label: Discount Rate
let lblDiscountRate = new Label()
lblDiscountRate.Left <- 18
lblDiscountRate.Top <- 48
lblDiscountRate.Width <- 80
lblDiscountRate.Text <- "Discount Rate:"
departmentStore.Controls.Add lblDiscountRate

// Text Box: Discount Rate
let txtDiscountRate = new TextBox()
txtDiscountRate.Left  <- 100
txtDiscountRate.Top   <- 43
txtDiscountRate.Width <- 40
txtDiscountRate.Text   <- "0.00"
departmentStore.Controls.Add txtDiscountRate

// Label: Percent
let lblPercent = new Label()
lblPercent.Left <- 140
lblPercent.Top <- 48
lblPercent.Width <- 20
lblPercent.Text <- "%"
departmentStore.Controls.Add lblPercent

// Button: Calculate
let btnCalculate = new Button()
btnCalculate.Left <- 164
btnCalculate.Top  <-  43
btnCalculate.Text <- "Calculate"

// Label: Marked Price
let lblMarkedPrice = new Label()
lblMarkedPrice.Left  <-  18
lblMarkedPrice.Top   <- 78
lblMarkedPrice.Width <-  80
lblMarkedPrice.Text  <- "Marked Price:"
departmentStore.Controls.Add lblMarkedPrice

// Text Box: Marked Price
let txtMarkedPrice = new TextBox()
txtMarkedPrice.Left  <- 100
txtMarkedPrice.Top   <- 75
txtMarkedPrice.Width <- 54
txtMarkedPrice.Text   <- "0.00"
departmentStore.Controls.Add txtMarkedPrice

// Button: Close
let btnClose = new Button()
btnClose.Left <- 164
btnClose.Top  <- 72
btnClose.Text <- "Close"
let btnCloseClick e = departmentStore.Close()
btnClose.Click.Add btnCloseClick
departmentStore.Controls.Add btnClose

let btnCalculateClick e =
    (:=) price (float txtUnitPrice.Text)
    (:=) discountRate (float txtDiscountRate.Text)

    (:=) discountAmount (price.Value * discountRate.contents / 100.00)
    markedPrice <- ((!) price - !discountAmount)

    let strMarkedPrice = sprintf "%0.02f" markedPrice
    txtMarkedPrice.Text <- strMarkedPrice

btnCalculate.Click.Add btnCalculateClick
departmentStore.Controls.Add btnCalculate

do Application.Run departmentStore

You can apply the same concept when creating a record object. You can start by declaring the variable as a reference cell. Here is an example:

type Customer = {
    AccountNumber   : int
    FirstName       : string
    MI              : char
    LastName        : string
    AccountIsActive : bool }

let cust = ref {
    AccountNumber = 0;
    FirstName = ""; MI = ' '; LastName = "";
    AccountIsActive = false }

To set the values of the variable, precede its name with (:=) and assign the desired values. Here is an example:

type Customer = {
    AccountNumber   : int
    FirstName       : string
    MI              : char
    LastName        : string
    AccountIsActive : bool }

let cust = ref {
    AccountNumber = 0;
    FirstName = ""; MI = ' '; LastName = "";
    AccountIsActive = false }

(:=) cust {
    AccountNumber = 952749;
    FirstName = "William"; MI = 'T'; LastName = "Leonardson";
    AccountIsActive = true }

Later on, to get to the value of a label, access it through the contents field or the Value property. Here are examples:

let acntNumber = cust.Value.AccountNumber
let fullName = cust.contents.FirstName + " " + cust.Value.LastName
     
     
 

Home Copyright © 2014-205 FunctionX Home