Functions

4.1 Defining and Calling

let square x = x * x                       // int -> int (inferred)
let add x y = x + y                        // int -> int -> int
let greet (name: string) = $"Hello, {name}!"
let area (w: float) (h: float) : float = w * h   // full annotations

square 5                                   // 25: application is by juxtaposition
add 2 3                                    // 5
add (square 2) 3                           // 7: parentheses group arguments

4.2 Currying and Partial Application

let add x y = x + y        // really int -> (int -> int)
let add10 = add 10         // partial application: int -> int
add10 5                    // 15

let multiply x y = x * y
let double = multiply 2
[1; 2; 3] |> List.map double        // [2; 4; 6]

// Tupled parameters (like C# methods): not curried
let addTupled (x, y) = x + y
addTupled (1, 2)

4.3 Lambdas, Closures and Recursion

let squares = List.map (fun x -> x * x) [1; 2; 3]    // [1; 4; 9]
let adder n = fun x -> x + n                         // returns a closure
let add5 = adder 5
add5 10                                              // 15

let rec factorial n = if n <= 1 then 1 else n * factorial (n - 1)   // rec enables recursion
let rec isEven n = if n = 0 then true else isOdd (n - 1)
and isOdd n = if n = 0 then false else isEven (n - 1)               // mutual recursion

// Lambda shorthand (F# 8): _.Property
let names = [ "ana"; "bo" ] |> List.map _.ToUpper()                 // ["ANA"; "BO"]

4.4 Generic and Inferred Types

let identity x = x                 // 'a -> 'a (automatically generic)
let pair x y = (x, y)              // 'a -> 'b -> 'a * 'b
let applyTwice f x = f (f x)       // ('a -> 'a) -> 'a -> 'a
applyTwice (fun n -> n * 2) 3      // 12

4.5 Operators as Functions and Custom Operators

(+) 2 3                            // 5
List.reduce (+) [1; 2; 3]          // 6
let (^+^) a b = a * 10 + b         // custom infix operator
3 ^+^ 4                            // 34
let (>>!) x f = f x; x             // a "tap" operator: apply f for side effects, return x
5 >>! printfn "%d" |> ignore