Higher-Order Functions and Folds

// fold: the universal list consumer
List.fold (fun acc x -> acc + x) 0 [1; 2; 3]            // 6
List.fold (fun acc x -> x :: acc) [] [1; 2; 3]          // [3; 2; 1] (reverse)
List.foldBack (fun x acc -> x :: acc) [1; 2; 3] []      // [1; 2; 3] (copy)

// Implement map and filter with fold
let myMap f xs = List.foldBack (fun x acc -> f x :: acc) xs []
let myFilter p xs = List.foldBack (fun x acc -> if p x then x :: acc else acc) xs []

// Aggregations with fold: min and max in one pass
let minMax xs =
    xs |> List.fold (fun (lo, hi) x -> (min lo x, max hi x)) (System.Int32.MaxValue, System.Int32.MinValue)
minMax [3; 1; 4; 1; 5]                                  // (1, 5)

// Functions returning functions, generic combinators
let compose f g = f >> g
let flip f a b = f b a
let curry f a b = f (a, b)
let uncurry f (a, b) = f a b
let tee f x = f x; x                                    // side effect, return the input
let retry times f =
    let rec go n = try f () with _ when n > 1 -> go (n - 1)
    go times