Thinking Functional with F#

https://dotnetfiddle.net/8rtpmV

F#

  • Functional (yet supports OO)
  • Feature-rich
  • Concise
  • Powerful type system
  • Encourages composition vs inheritance

Cool Things

  • Pattern Matching
  • Algebraic Data Types
  • Active Patterns
  • Tail/Mutual Recursion Optimization
  • If it compiles it probably just works

ADTs - F#


type Currency = Currency of decimal

type Tree =
    | Branch of T * Tree * Tree
    | Leaf of T

ADTs - C#

[Serializable]
public class Currency :
    IEquatable<Currency>,
    IStructuralEquatable,
    IComparable<Currency>,
    IComparable,
    IStructuralComparable
{
    public decimal Value { get; private set; }
    public void Currency(decimal value) { this.Value = value; }

    ..about 300 lines of interface implementation..
}

Recursion - F#

let rec fib n =
    match n with
    | 0 -> 0
    | 1 -> 1
    | _ -> fib(n-1) + fib(n-2)

Recursion - C#

static int Fib(int x)
{
    switch (x) {
      case 0: return 0;
      case 1: return 1;
      default: return Fib(x - 1) + Fib(x - 2);
    }
}

Active Patterns

let (|Regex|_|) pattern input =
    let m = Regex.Match(input, pattern)
    if m.Success then Some(List.tail [ for g in m.Groups -> g.Value ])
    else None

let parsed = match input with
             | Regex @"^\$([\d]+\.[\d]{2})$" [value] -> Convert.ToDecimal(value)
             | Regex @"^([\d]+\.[\d]{2})$" [value]   -> Convert.ToDecimal(value)
             | Regex @"^(\.[\d]{2})$" [value]        -> Convert.ToDecimal(value)
             | _  -> raise(InputError "Invalid input, please try again.")

Functional Approach in C#

  • Immutable vs Mutable
  • Isolation of state
  • Start with small, pure functions
  • Compose into complex pieces
  • View systems as a pipeline of transformations
  • Transformations are just functions

Thinking Functional with F#

By Paul Schoenfelder

Thinking Functional with F#

5 minute presentation on F# for coworkers

  • 918