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