Home

Function Values

   

Description

By definition, a function in F# is a value. Because a function is a value, it can be passed to another function as argument. Such a function is passed by its signature. The formula to follow is:

 

 
let function-name (function-parameter) parameter(s) = ...

You start with the let keyword followed by the function you want to define and its parentheses. In the parentheses, specify the signature of the function starting with its name. Here is an example:

let getPerimeter (calc : float -> float) ...

This example specifies that we are passing a function value that takes an argument as float and that function will return a float. Outside the parentheses, you should specify a name for the argument the function value takes. In the body of the function, call the function value and pass the parameter to it. Here is an example:

let getPerimeter (calc : float -> float) side = calc side

In order to call the function, you must have another function that actually implements the behavior of the function value. When calling the function, pass the name of that other function followed by a value for the argument. Here is an example:

let multiplyBy4 nbr = nbr * 4.00

let getPerimeter (calc : float -> float) side = calc side

let result = getPerimeter multiplyBy4 25.97

By tradition, the function value is named pred, which stands for predicate, but this is not a requirement.

Just like you can use a function value with one argument, you can pass a function value that takes as many arguments as you want. Follow the same logic we described. Here is an example:

open System
open System.Windows.Forms

let add x y = x + y

let calculateNetPrice(addition : float -> float -> float) a b = addition a b
let calculateTaxAmount amount taxRate = amount * taxRate / 100.00

// Form: Convenience Store
let convenienceStore : Form = new Form()
convenienceStore.Width  <- 268
convenienceStore.Height <- 150
convenienceStore.Text <- "Convenience Store"

// Label: Purchase Price
let lblPurchasePrice : Label = new Label()
lblPurchasePrice.Left <- 18
lblPurchasePrice.Top  <- 24
lblPurchasePrice.Width <- 85
lblPurchasePrice.Text <- "Purchase Price:"
convenienceStore.Controls.Add lblPurchasePrice

// Text Box: PurchasePrice
let txtPurchasePrice : TextBox = new TextBox()
txtPurchasePrice.Left <- 106
txtPurchasePrice.Top <- 21
txtPurchasePrice.Width <- 60
txtPurchasePrice.Text <- "0.00"
convenienceStore.Controls.Add txtPurchasePrice

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

// Label: Tax Amount
let lblTaxAmount : Label = new Label()
lblTaxAmount.Left <- 18
lblTaxAmount.Top <- 55
lblTaxAmount.Width <- 85
lblTaxAmount.Text <- "Tax Amount:"
convenienceStore.Controls.Add lblTaxAmount

// Text Box: Tax Amount
let txtTaxAmount : TextBox = new TextBox()
txtTaxAmount.Left <- 106
txtTaxAmount.Top <- 51
txtTaxAmount.Width <- 60
txtTaxAmount.Text <- "0.00"
convenienceStore.Controls.Add txtTaxAmount

// Label: Part 1 Receives
let lblNetPrice : Label = new Label()
lblNetPrice.Left  <-  18
lblNetPrice.Top   <-  85
lblNetPrice.Width <-  60
lblNetPrice.Text  <- "Net Price:"
convenienceStore.Controls.Add lblNetPrice

// Text Box: Part 1 Value
let txtNetPrice : TextBox = new TextBox()
txtNetPrice.Left  <- 106
txtNetPrice.Top   <-  82
txtNetPrice.Width <-  60
txtNetPrice.Text <- "0.00"
convenienceStore.Controls.Add txtNetPrice

// Button: Close
let btnClose : Button = new Button()
btnClose.Left <- 173
btnClose.Top  <- 80
btnClose.Text <- "Close"

let btnCalculateClick _ =
    let amount    = float txtPurchasePrice.Text
    let taxAmount = calculateTaxAmount amount 6.75
    let netPrice  = calculateNetPrice add amount taxAmount
    let strTaxAmount = sprintf "%0.02f" taxAmount
    let strNetPrice = sprintf "%0.02f" netPrice

    txtTaxAmount.Text <- strTaxAmount
    txtNetPrice.Text <- strNetPrice
btnCalculate.Click.Add btnCalculateClick
convenienceStore.Controls.Add btnCalculate

let btnCloseClick e = convenienceStore.Close()
btnClose.Click.Add btnCloseClick
convenienceStore.Controls.Add btnClose

do Application.Run convenienceStore

This would produce:

Function Values

You can pass as many function values as necessary to a function. After the name of the function, create the parentheses for each function value. In the parentheses of each function value, specify its name and the appropriate signature. After the last parentheses, create the list of the parameters that the function value(s) will use. The function values can share parameters or any of them can call (one of) the other function value(s) to get its return value and use it. Otherwise, the logic uses the techniques used for functions. Here is an example:

open System
open System.Windows.Forms

let add2Values a b = a + b
let multiply3Values a b c = a * b * c

let calculateInterest (statement : float -> float -> float -> float) (totalize : float -> float -> float) printcipal rate periods =
    let totalInterest = statement printcipal rate periods
    totalize printcipal totalInterest

// Compound Interest
let simpleInterest : Form = new Form()
simpleInterest.Text <- "Compound Interest"
simpleInterest.Width <- 290
simpleInterest.Height <- 180

// Label: Principal
let lblPrincipal : Label = new Label()
lblPrincipal.Text   <- "Principal:"
lblPrincipal.Left   <- 19
lblPrincipal.Top    <- 23
lblPrincipal.Width  <- 72
simpleInterest.Controls.Add lblPrincipal

// Text Box: Principal
let txtPrincipal : TextBox = new TextBox()
txtPrincipal.Text  <- "0.00"
txtPrincipal.Left  <- 95
txtPrincipal.Top   <- 20
txtPrincipal.Width <- 64
simpleInterest.Controls.Add txtPrincipal

// Label: Interest Rate
let lblInterestRate : Label = new Label()
lblInterestRate.Text  <- "Interest Rate: 10.25%"

lblInterestRate.Left  <- 18
lblInterestRate.Top   <- 49
lblInterestRate.Width <- 180
simpleInterest.Controls.Add lblInterestRate

// Label: Periods
let lblPeriods : Label = new Label()
lblPeriods.Text  <- "Periods:"
lblPeriods.Left  <- 18
lblPeriods.Top   <- 75
lblPeriods.Width <- 75
simpleInterest.Controls.Add lblPeriods

// Text Box: Periods
let txtPeriods : TextBox = new TextBox()
txtPeriods.Text  <- "0"
txtPeriods.Left  <- 95
txtPeriods.Top   <- 72
txtPeriods.Width <- 45
simpleInterest.Controls.Add txtPeriods

// Label: Years
let lblYears : Label = new Label()
lblYears.Text  <- "Years"
lblYears.Left  <- 146
lblYears.Top   <- 75
lblYears.Width <- 40
simpleInterest.Controls.Add lblYears

// Button: Calculate
let btnCalculate : Button = new Button()
btnCalculate.Text <- "Calculate"
btnCalculate.Left <- 186
btnCalculate.Top <- 72
simpleInterest.Controls.Add btnCalculate

// Label: Future Value
let lblFutureValue : Label = new Label()
lblFutureValue.Left  <- 19
lblFutureValue.Top   <- 112
lblFutureValue.Width <- 75
lblFutureValue.Text  <- "Future Value:"
simpleInterest.Controls.Add lblFutureValue

// Text Box: Future Value
let txtFutureValue : TextBox = new TextBox()
txtFutureValue.Text  <- "0.00"
txtFutureValue.Left  <- 95
txtFutureValue.Top   <- 110
txtFutureValue.Width <- 64
simpleInterest.Controls.Add txtFutureValue

let btnCalculateClick e =
    let principal = float txtPrincipal.Text
    let interestRate = 10.25
    let periods = float txtPeriods.Text

    let futureValue = calculateInterest multiply3Values add2Values principal (interestRate / 100.00) periods

    let strFutureValue = sprintf "%0.02f" futureValue
    txtFutureValue.Text <- strFutureValue

btnCalculate.Click.Add btnCalculateClick

// Button: Close
let btnClose : Button = new Button()
btnClose.Text <- "Close"
btnClose.Left <- 186
btnClose.Top <- 108
let btnCloseClick _ =
    simpleInterest.Close()
btnClose.Click.Add btnCloseClick
simpleInterest.Controls.Add btnClose   

do Application.Run simpleInterest

Here is an example of running the program:

Function Values

In our example, we declared a variable to temporarily hold the returned value of the first function value. If you are not planning to use that return value many times, you don't have to store it in a variable. You can directly call the function value where it is needed in the body of the function. In this case, you must include it in parentheses. Here is an example:

let calculateInterest (statement : float -> float -> float -> float) (totalize : float -> float -> float) printcipal rate periods =
    totalize printcipal (statement printcipal rate periods)
     
     
 

Home Copyright © 2009-2015, FunctionX Home