Home

Functions Delegates

   

Introduction

The Action delegate is used for unit functions or class methods that don't return a value. To support functions and methods that return a value, the .NET Framework provides a delegate named Func. As seen for the Action type, the Func delegate is delivered in various versions that take different parameters.

The most fundamental version of a function delegate uses the following syntax:

type Func = 
    delegate of unit -> 'TResult

Notice that instead of the Action word, Func is used. This version is for a function or method that takes no parameter but returns a value. Notice that the return value is a generic type. This means that you must specify the type of value that the function or method must return. To do this, enter the type after the Func name between < and >. Everthing else is as we saw for the Action delegate. Remember that the function returns a value. You can get that value and store it in a variable if you want. Here is an example:

open System
open System.Windows.Forms 

let exercise = new Form(Width = 400, Height = 130, Text = "Restaurant Business - Orientation")

let lblIntroduction = new Label(Width = 350, Height = 100, Left = 23, Top = 18)
exercise.Controls.Add lblIntroduction

let introduce() =
    "Welcome to Four-Corner restaurant. We serve the best exotic meals in the region. " +
    "Our selection includes soups, sauce, meals, and appetizers. During the week, " +
    "from Monday to Friday, we serve the Lunch Special when the prices of most of " +
    "meals are reduced. Come and try our tastes. You will be delighted."

let description = Func<string>(introduce)

let result = description.Invoke();

lblIntroduction.Text <- "Restaurant Introduction: " + result

[<EntryPoint>]
let main argv = 
    Application.Run exercise
    0

This would produce:

Functions Delegates

If you don't need to use the return value many times, you don't have to store it in a variable. You can directly call the Invoke() method where the return value is needed. Here is an example:

open System
open System.Windows.Forms 

let exercise = new Form(Width = 400, Height = 130, Text = "Restaurant Business - Orientation")

let lblIntroduction = new Label(Width = 350, Height = 100, Left = 23, Top = 18)
exercise.Controls.Add lblIntroduction

let introduce() =
    "Welcome to Four-Corner restaurant. We serve the best exotic meals in the region. " +
    "Our selection includes soups, sauce, meals, and appetizers. During the week, " +
    "from Monday to Friday, we serve the Lunch Special when the prices of most of " +
    "meals are reduced. Come and try our tastes. You will be delighted."

let description = Func<string>(introduce)

lblIntroduction.Text <- "Restaurant Introduction: " + description.Invoke()

[<EntryPoint>]
let main argv = 
    Application.Run exercise
    0

In the same way, you don't have to formally declare a variable for Func. You can directly use it where needed. Here is an example:

(Func<string>(introduce)).Invoke()

As its name indicates, the primary purpose of a function delegate is to return a value. The value can be a primitive type or a class type. Here is an example for a class type:

open System
open System.Windows.Forms 

let exercise = new Form(Width = 200, Height = 160, Text = "Exercise")

let lblEmployeeNumber  = new Label(Left = 23, Top = 18, Width = 180)
exercise.Controls.Add lblEmployeeNumber 

let lblEmployeeName  = new Label(Left = 23, Top = 43, Width = 180)
exercise.Controls.Add lblEmployeeName 

let lblEmploymentStatus = new Label(Left = 23, Top = 69, Width = 180)
exercise.Controls.Add lblEmploymentStatus

let lblHourlySalary  = new Label(Left = 23, Top = 96, Width = 180)
exercise.Controls.Add lblHourlySalary

type Employee() =
    let mutable emplNbr = ""
    let mutable fn = ""
    let mutable ln = ""
    let mutable sts = ""
    let mutable sal  = 0.00
    member this.EmployeeNumber with get() = emplNbr and set(value) = emplNbr <- value
    member this.FirstName with get() = fn and set(value) = fn <- value
    member this.LastName with get() = ln and set(value) = ln <- value
    member this.Status with get() = sts and set(value) = sts <- value
    member this.HourlySalary with get() = sal and set(value) = sal <- value
    
let createEmployeeRecord() =
    let empl : Employee = Employee()
    empl.EmployeeNumber <- "4029-3940"
    empl.FirstName <- "Mary Anne"
    empl.LastName <- "Bergmann"
    empl.Status <- "Part-Time"
    empl.HourlySalary <- 28.05
    empl

let presentation = Func<Employee>(createEmployeeRecord)

let empl = presentation.Invoke()

lblEmployeeNumber.Text <- "Employee #: " + empl.EmployeeNumber
lblEmployeeName.Text <- "Full Name: " + empl.FirstName + " " + empl.LastName
lblEmploymentStatus.Text <- "Status: " + empl.Status
lblHourlySalary.Text <- "Hourly Salary: " + (string empl.HourlySalary)

do Application.Run exercise

This would produce:

Functions Delegates

     
 

Characteristics of Function Delegates

We already know how to specify the return value of a function. One of the characteristics of delegates is that they can take parameters. This also applies to Functions. To specify the parameter of a Func delegate, in its <> operator, after <, enter the parameter type, followed by a comma, and the return type. Here is an example:

Func<int, string>()

In the parentheses, pass the name of the function that implements the delegate. When calling the Invoke() function, pass an argument that is the type specified in Func.

In the same way, a function can take more than one parameter and you must indicate their types. As mentioned already, the Func delegate is available in various versions for different numbers of parameters. To specify the types of the parameters, after the < operator of Func, enter the types separated by commas, and end with the return type of the function. Here is an example for a function that takes two arguments:

open System
open System.Windows.Forms

let calculateGrossPay items vale = items * vale
let calculate = Func<float, float, float>(calculateGrossPay)

let truckDriving = new Form(Width = 205, Height = 200, Text = "Truck Driving")

truckDriving.Controls.Add(new Label(Left = 21, Top = 23, Width = 72, Text =  "Miles Driven:"))
let txtMilesDriven = new TextBox(Left = 95, Top = 20, Width = 74, Text = "0.00")
truckDriving.Controls.Add txtMilesDriven

truckDriving.Controls.Add(new Label(Left = 21, Top = 49, Width = 72, Text =  "Price:"))
let txtPricePerMile = new TextBox(Left = 95, Top = 46, Width = 44, Text = "0.00")
truckDriving.Controls.Add txtPricePerMile
truckDriving.Controls.Add(new Label(Left = 144, Top = 49, Width = 30, Text =  "/Mile"))

truckDriving.Controls.Add(new Label(Left = 21, Top = 104, Width = 72, Text =  "Gross Pay:"))
let txtGrossPay = new TextBox(Left = 95, Top = 101, Width = 74, Text = "0.00")
truckDriving.Controls.Add txtGrossPay

let btnCalculate = new Button(Left = 95, Top = 72, Text = "Calculate")

let btnClose = new Button(Left = 95, Top = 135, Text = "Close")
let btnCloseClick _ = truckDriving.Close()
btnClose.Click.Add btnCloseClick
truckDriving.Controls.Add btnClose

let btnCalculateClick e =
    let milesDriven = float txtMilesDriven.Text
    let rate        = float txtPricePerMile.Text
    let pay         = calculateGrossPay milesDriven, rate
    let payment     = calculate
    let strGrossPay = sprintf "%0.02f" (payment.Invoke( milesDriven, rate))

    txtGrossPay.Text <- strGrossPay

btnCalculate.Click.Add btnCalculateClick
    
truckDriving.Controls.Add btnCalculate

Application.Run truckDriving

Here is an example of testing the program:

Characteristics of Function Delegates Characteristics of Function Delegates

Remember that the parameters are generic and can be any type. In fact, you can use a combination of classes and primitive types.

A function delegate uses the same characteristics of regular functions and methods. For example, a function delegate can be passed as parameter to a function or a method. Here is an example:

open System
open System.Windows.Forms 

let exercise = new Form(Width = 265, Height = 80, Text = "Exercise")

let lblCourseDecription = new Label(Left = 21, Top = 18, Width = 260)
exercise.Controls.Add lblCourseDecription

let initialyze courseName credits =
    courseName + "(" + (string credits) + ")"

let createCatalog (init : Func<string, int, string>) name title credits =
    let course =  new Func<string, int, string>(initialyze)
    name + ": " + course.Invoke(title, credits)

let catalogue = Func<Func<string, int, string>, string, string, int, string>(createCatalog)
let init = Func<string, int, string>(initialyze)
let result = catalogue.Invoke(init, "CMIS 226", "Enterprise Database Design", 3)

lblCourseDecription.Text <- result

do Application.Run exercise

This would produce:

Functions Delegates

Remember that you can omit declaring variables that you don't need, like this:

let catalogue = Func<Func<string, int, string>, string, string, int, string>(createCatalog)

let result = catalogue.Invoke(Func<string, int, string>(initialyze), "CMIS 226", "Enterprise Database Design", 3)

Or like this:

let result = (Func<Func<string, int, string>, string, string, int, string>(createCatalog)).Invoke(Func<string, int, string>(initialyze), "CMIS 226", "Enterprise Database Design", 3)

As another characteiristic, a method of a class can be passed to a function delegate.

 

   
   
 

Home Copyright © 2015 FunctionX Home