F# as a Medium for Functional Thinking

To demonstrate the practical value of thinking functionally while developing software in F#

Purpose

Thinking with functions

defined by expressions

applied as transformations

to a sequence

= x - x^3/6
=xx3/6
f(x)
f(x)

of immutable data

Thinking with functions defined by expressions applied as transformations to a sequence

of immutable data

Pure Functions (a la Math)

let function input = output
f(x) = ...x...
f(x)=...x...

Thinking with functions defined by expressions applied as transformations to a sequence

of immutable data

Statements are executed

var trimmed = "";
if (toTrim != null)
{
    trimmed = toTrim.Trim();
}
return trimmed;
var x = 2;
return x;

Expressions are evaluated

2
2
3^2 + 4^2
32+42
\alpha\sin(\theta \div 2) + \beta
αsin(θ÷2)+β
if toTrim = null
then ""
else toTrim.Trim()
x
x

Statement-based (C#)

class Cell {
    public bool IsAlive { get; set; }
    public Cell NextState(int livingNeighbors)
    {
	if ((IsAlive && livingNeighbors == 2) ||
            livingNeighbors == 3)
        {
            return new Cell { IsAlive = true };
        }
        return new Cell { IsAlive = false };
    }
}

Algebraic Data Types

type ParseResult =
    | Success of Expression
    | Incomplete
    | Failure of string
type Option<'a> = None | Some of 'a

Pattern Matching

match parseResult with
| Succeeded expr ->
    print (evaluate expr)
| Failed message ->
    printError message
| Incomplete ->
    evalAndPrint (readAnotherLine())

Expression-based (F#)

type Cell = DeadCell | LivingCell

let nextStateOf cell livingNeighbors =
    match cell, livingNeighbors with
    | LivingCell, 2 -> LivingCell
    | _, 3 -> LivingCell
    | _ -> DeadCell

Thinking with functions defined by expressions applied as transformations to a sequence
of immutable data

Imperative (C#)

public bool ShouldOfferToGiftWrap()
{
    foreach (var item in Items)
    {
        if (item.IsFromWishlist)
        {
            return true;
        }
    }

    return false;
}

Functional (F#)

let shouldOfferToWrapGift order =
    List.exists (fun i -> i.IsFromWishlist) order.Items

Map

Reduce

Matching & Transforming

let selectDaleks aggregate episode =
    match episode with
    | 0, _ -> aggregate
    | 1, episodeName ->
        sprintf "%s\n1 dalek in %s" aggregate episodeName
    | n, episodeName ->
        sprintf "%s\n%i daleks in %s" aggregate n episodeName

List.fold selectDaleks "Dalek episodes:" episodes |> printf "%s"

Lazy Sequences

seq { ... }
1, 2, 4, 8, 16...
1,2,4,8,16...

Fibonacci/FizzBuzz

Input Stream

Thinking with functions defined by expressions applied as transformations to a sequence
of immutable data

Changing vs Transforming

vs

Natural Immutability

type Pizza = {
    Name : string
    Ingredients : string list
    IsDeluxe : bool
}

let pepperoni = {
    Name = "Pepperoni"
    Ingredients = ["Pepperoni"; "Cheese"]
    IsDeluxe = false
}

{ pepperoni with Ingredients = "mushrooms" :: pizza.Ingredients }

Functions are Practical

Powerful Composition

List.filter hasDaleks doctorWhoEpisodes
|> List.map (fun episode -> episode.Name)
|> printf "Favorite episodes: %A"
onlyDalekEpisodes doctorWhoEpisodes
|> List.map (fun episode -> episode.Name)
|> printf "Favorite episodes: %A"

Compose Operator

let plusThree x = x + 3
let timesTwo x = x * 2


let plusThreeTimesTwo =
    plusThree >> timesTwo

// Or just
let plusThreeTimesTwo =
    (+) 3 >> (*) 2

Partial Application

let hasDaleks episode =
    ...

let onlyDalekEpisodes =
    List.filter hasDaleks
(* Same as
 * let onlyDalekEpisodes episodes =
 *     List.filter hasDaleks episodes
 * *)

onlyDalekEpisodes episodes

Chaining functions

onlyDalekEpisodes doctorWhoEpisodes
|> List.map (fun episode -> episode.Name)
|> printf "Favorite episodes: %A"

Composition & Sequences

lazyLoadFromDisk()
|> Seq.filter ...
|> Seq.map ...
|> Seq.reduce ...
|> writeToDisk

Could you simplify your code by thinking in terms of transformations on immutable data?

Could you simplify your code by writing it in F#?

Think Functionally

Write F#

F# as a Medium for Functional Thinking

By Keith Pinson

F# as a Medium for Functional Thinking

The practical value of thinking functionally and expressing it in F#

  • 1,863

More from Keith Pinson