1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
module Delegates
// The following code shows the syntax for creating delegates that represent various methods in a class.
// Depending on whether the method is a static method or an instance method,
// and whether it has arguments in the tuple form or the curried form,
// the syntax for declaring and assigning the delegate is a little different.
type Test1() =
static member add(a : int, b : int) =
a + b
static member add2 (a : int) (b : int) =
a + b
member x.Add(a : int, b : int) =
a + b
member x.Add2 (a : int) (b : int) =
a + b
let replicate n c = String.replicate n (string c)
// Delegate specifications must not be curried types.
// Use 'typ * ... * typ -> typ' for multi-argument delegates,
// and 'typ -> (typ -> typ)' for delegates returning function values.
type Delegate1 = delegate of (int * int) -> int// Delegate1 works with tuple arguments.
type Delegate2 = delegate of int * int -> int // Delegate2 works with curried arguments.
type Delegate3 = delegate of int * char -> string
type Delegate4 = delegate of int -> (int -> char)
type Delegate5 = delegate of int -> (int -> char -> string)
type Delegate6 = delegate of (int -> float) -> char
type Delegate7 = delegate of (int -> char -> string) -> float
type Delegate8 = delegate of int -> char
type Delegate9 = delegate of (int * int) -> char
type Delegate10 = delegate of int * int -> char
type Delegate11 = delegate of char -> unit
type Delegate12 = delegate of unit -> char
type Delegate13 = delegate of (int -> char -> string -> decimal) -> float
let function1(i : int, i2 : int) = 1
let function2(i : int) (ch : int) = 1
let function3(i : int) (s : char) = ""
let function4(i : int) (ch : int) = ' '
let function5(i : int) (i2 : int) (ch : char) = ""
let function6(intIntFunction : int -> float) = ' '
let function7(intCharStringFunction : int -> char -> string) = 0.5
let function8(i : int) = ' '
let function9(i : (int * int)) = ' '
let function10(i : int) (i2 : int) = ' '
let function11(c : char) = ()
let function12(c : unit) = ' '
let function12_1() = ' '
let function13(intCharStringDecimalFunction : int -> char -> string -> decimal) = 0.5
let delObject1 = new Delegate1(function1)
let delObject2 = new Delegate2(function2)
let delObject3 = new Delegate3(function3)
let delObject4 = new Delegate4(function4)
let delObject5 = new Delegate5(function5)
let delObject6 = new Delegate6(function6)
let delObject7 = new Delegate7(function7)
let delObject8 = new Delegate8(function8)
let delObject9 = new Delegate9(function9)
let delObject10 = new Delegate10(function10)
let delObject11 = new Delegate11(function11)
let delObject12 = new Delegate12(function12)
let delObject12_1 = new Delegate12(function12_1)
let delObject13 = new Delegate13(function13)
let InvokeDelegate1 (dlg : Delegate1) (a : int) (b: int) =
dlg.Invoke(a, b)
let InvokeDelegate2 (dlg : Delegate2) (a : int) (b: int) =
dlg.Invoke(a, b)
// For static methods, use the class name, the dot operator, and the
// name of the static method.
let del1 : Delegate1 = new Delegate1( Test1.add )
let del2 : Delegate2 = new Delegate2( Test1.add2 )
let testObject = Test1()
// For instance methods, use the instance value name, the dot operator, and the instance method name.
let del3 : Delegate1 = new Delegate1( testObject.Add )
let del4 : Delegate2 = new Delegate2( testObject.Add2 )
for (a, b) in [ (100, 200); (10, 20) ] do
printfn "%d + %d = %d" a b (InvokeDelegate1 del1 a b)
printfn "%d + %d = %d" a b (InvokeDelegate2 del2 a b)
printfn "%d + %d = %d" a b (InvokeDelegate1 del3 a b)
printfn "%d + %d = %d" a b (InvokeDelegate2 del4 a b)
// The following code shows some of the different ways you can work with delegates.
// An F# function value constructed from an unapplied let-bound function
let function1_ = replicate
// A delegate object constructed from an F# function value
let delObject = new Delegate3(function1_)
// An F# function value constructed from an unapplied .NET member
let functionValue = delObject.Invoke
List.map (fun c -> functionValue(5,c)) ['a'; 'b'; 'c']
|> List.iter (printfn "%s")
// Or if you want to get back the same curried signature
let replicate' n c = delObject.Invoke(n,c)
// You can pass a lambda expression as an argument to a function expecting a compatible delegate type
// System.Array.ConvertAll takes an array and a converter delegate that transforms an element from
// one type to another according to a specified function.
let stringArray = System.Array.ConvertAll([|'a';'b'|], fun c -> replicate' 3 c)
printfn "%A" stringArray
|