Design Patterns in F#
Steve Goguen
Steve Goguen
Convinced mutating state is the root of all evil.
Website: www.njgeeks.com
Peter Norvig noted that many of the 23 design patterns were significantly simplified or eliminated with higher level languages.
…if thought corrupts language, language can also corrupt thought.

Functional F#
let ReadFolder = Directory.GetFiles >> Array.map File.ReadAllText
Imperative C#
string[] ReadFolder(string path) {
var filenames = Directory.GetFiles(path);
var results = new string[filenames.Length];
for(var i = 0; i < results.Length; i++) {
var filename = filenames[i];
var text = File.ReadAllText(filename);
results[i] = text;
}
return results;
}
Could ceremony and painstaking attention to the details corrupt your thinking and distract you from solving your problem?
Functional C#
string[] ReadFolder(string path) {
return Directory.GetFiles(path).Select(f => File.ReadAllText(f)).ToArray();
}
Functional F#
let ReadFolder = Directory.GetFiles >> Array.map File.ReadAllText
Functional C# with LINQ
string[] ReadFolder(string path) {
return (from f in Directory.GetFiles(path)
select File.ReadAllText(f)).ToArray();
}
Functional F#
let ReadFolder = Directory.GetFiles >> Array.map File.ReadAllText
let add x y = x + y
Directory.GetFiles - // Different output for same input System.IO.File.WriteAllText - // Affects the outside world
let add x y = x + y let z = add 4 5
The function's body can be substituted like so:
let z = 4 + 5
let files = Directory.GetFiles(@"C:\Test") let files1 = files let files2 = files
Substitution changes behavior
let files1 = Directory.GetFiles(@"C:\Test") let files2 = Directory.GetFiles(@"C:\Test")
let add x y = x + y let add2 = fun x y -> x + y let add3 = fun x -> fun y -> x + y
Func<int,Func<int,int>> Add = (x => { return y => { return x + y; }; });
'a
|
Support for simple types |
'a -> 'b
|
Functions |
'a * 'b
|
Tuples |
'a + 'b
|
Discriminated Unions |
| Example | Meaning |
|---|---|
string
|
A string type |
string * int
|
A tuple. Example ("Hello", 5) |
string + int
|
Something that can either be a string or an integer, but not both.
Note: Syntax not supported in F# |
string -> int
|
A function that takes a string and returns an integer |
unit -> int
|
A function that takes a nothing and returns an integer |
string -> unit
|
A function that takes a string and returns nothing |
'a
|
A generic type |
'a -> 'a
|
A function that accepts any type of object and returns an object of the same type |
('a -> 'b) -> (List<'a> -> List<'b>)
|
A function that takes any function (from 'a to 'b) and returns a function that a List<'a> and returns a List<'b> |
'a
|
Support for simple types |
'a -> 'b
|
Functions |
'a * 'b
|
Tuples |
'a + 'b
|
Discriminated Unions |
This assumes we're talking about pure functions
'a -> IO<'b>
|
Let's wrap non-pure values in an IO type |
'a
|
A value |
() -> 'a
|
Function - no args returning a value |
() -> IO<'a>
|
Function returning some input |
'a -> 'a
|
A pure function returning its own type |
'a -> 'b
|
A regular function |
'a * 'b
|
Tuples |
'a + 'b
|
Discriminated Unions |
This assumes we're talking about pure functions

One is clearly dumbu and the others are borou.



Do names define rigid mental boundaries?


Do these names distort our perspective?
|
|
|
Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.
interface IEmployee {
string Name { get; }
decimal GetCheckAmount();
}
interface IEmployeeFactory {
IEmployee Create(string name, string position);
}
public class SalariedEmployee : IEmployee {
// Our private fields to store our values
private string name;
private decimal yearlySalary;
// Constructor
internal SalariedEmployee (string name, decimal yearlySalary) {
this.name = name;
this.yearlySalary = yearlySalary;
}
// Readonly Name property
string IEmployee.Name {
get { return name; }
}
// Function to calculate a check amount
decimal IEmployee.GetCheckAmount() {
return yearlySalary / 52;
}
}
Create a class implementing IEmployeeFactory
public class SalariedEmployeeFactory : IEmployeeFactory {
public IEmployee Create(string name, string position) {
if(position == "boss")
return new SalariedEmployee(name, 300000);
return new SalariedEmployee(name, 40000);
}
}
public class FactoryExamples {
public void Example1() {
IEmployeeFactory f = new SalariedEmployeeFactory();
IEmployee[] Employees = new IEmployee[] {
f.Create("Larry", "stooge"),
f.Create("Curly", "stooge"),
f.Create("Moe", "boss")
};
}
}
All that code just to create some lousy objects??? Really???
Step 1: Define the Employee interface (The factory will just be a function)
type IEmployee = abstract member Name: string abstract member GetCheckAmount: unit -> decimal
Step 2: Create a function returning an object implementing IEmployee
let createSalaryEmployee(name,position) =
let yearlySalary = if position = "boss" then 300000.0m else 40000.0m
{ new IEmployee with
member this.Name = name
member this.GetCheckAmount() = yearlySalary / 52.0m }
Step 3: Try out our constructor
// Let's try this out
let employee = createSalaryEmployee
let employees = [
employee("Larry", "stooge")
employee("Curly", "stooge")
employee("Moe", "boss")
]
C# Version
class A {
public private A() {}
private static A instance = new A();
public static A Instance() {
return
}
public void Action() {
Console.Write("action");
}
}
type A private () =
static let instance = A()
static member Instance = instance
member this.Action() = printfn "action"
let DesignPattern1() =
let a = A.Instance;
a.Action()
| F# | C# |
|---|---|
let makeSingleton f = let instance = f() fun () -> instance |
Func<A> makeSingleton<A>(Func<A> f) {
var instance = f();
return () => instance;
}
|
Let's try it out!
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
public interface Coffee {
public double getCost();
public String getIngredients();
}
public class SimpleCoffee : Coffee {
public double getCost() { return 1; }
public String getIngredients() { return "Coffee"; }
}
public class Milk : Coffee {
private Coffee decoratedCoffee;
public Milk(Coffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
}
public double getCost() { // overriding methods defined in the abstract superclass
return decoratedCoffee.getCost() + 0.5;
}
public String getIngredients() {
return decoratedCoffee.getIngredients() + ingredientSeparator + "Milk";
}
}
type Coffee =
abstract member getCost: unit -> double
abstract member getIngredients: unit -> string
let SimpleCoffee =
{ new Coffee with
member this.getCost() = 1.0
member this.getIngredients() = "Coffee"
}
let Milk(coffee:Coffee) =
{ new Coffee with
member this.getCost() = coffee.getCost() + 0.5
member this.getIngredients() = coffee.getIngredients() + ", " + "milk"
Let's try this out
let myCoffee = Milk(SimpleCoffee)
We could pipe it too
let myCoffee = SimpleCoffee |> Milk
Separate the construction of a complex object from its representation allowing the same construction process to create various representations.
class CoffeeBuilder {
protected Coffee coffee;
public Coffee getCoffee() {
return coffee;
}
public void createNewCoffeeProduct() {
coffee = new SimpleCoffee();
}
public void addMilk() {
coffee = new Milk(coffee);
}
}
// Usage var builder = new CoffeeBuilder(); builder.createNewCoffeeProduct(); builder.addMilk(); var myCoffee = builder.getCoffee();
class CoffeeBuilder {
protected Coffee coffee;
public Coffee getCoffee() {
return coffee;
}
public CoffeeBuilder createNewCoffeeProduct() {
coffee = new SimpleCoffee();
return this;
}
public CoffeeBuilder addMilk() {
coffee = new Milk(coffee);
return this;
}
}
// Usage var myCoffee = new CoffeeBuilder() .createNewCoffeeProduct().addMilk().getCoffee();
Define our fluent builder
type CoffeeBuilder(coffee:Coffee) = new() = CoffeeBuilder(SimpleCoffee) member this.addMilk() = CoffeeBuilder(Milk(coffee)) member this.getCoffee() = coffee
Use it
let builder = new CoffeeBuilder() let myCoffee = builder.addMilk().getCoffee()
Why create a fluent interface when you can just pipe constructors?
let myCoffee = SimpleCoffee |> Milk
Do F# Sequences use the Builder Pattern?
let myFunctions = let path = @"C:\Project" Directory.EnumerateFiles(path, "*.vb", SearchOption.AllDirectories) |> Seq.map File.ReadAllText |> Seq.collect (fun text -> Regex.Matches(text, "Function \w+\([^)]*\)") |> Seq.cast) |> Seq.map (fun m -> m.Value) |> Seq.take 10
| Pattern | Type |
|---|---|
| Singleton - Ensure a class has only one instance, and provide a global point of access to it. |
() -> 'a
|
| Factory Method |
'a -> 'b
|
| Lazy Initialization - Delay creating an until the first time it's needed |
() -> 'a
|
| Prototype - Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype |
'a -> () -> 'a
|
| Adaptor - Convert the interface of a class into another interface clients expect. |
'a -> 'b
|
| Abstract Factory - Provide an interface for creating families of related or dependent objects |
('a -> 'b) * ('c -> 'd)
|
| Multiton - Ensure a class has only named instances, and provide global point of access to them |
string -> 'a
|
| Pattern | Type |
|---|---|
| Decorator - Attach additional responsibilities to an object dynamically keeping the same interface. |
'b -> 'a -> 'a
|
| Builder |
'a -> 'b -> 'c
|
| Composite |
List<'a> -> 'a
|
In computing science, more abstract viewpoints are often more useful, because of the need to achieve independence from the often overwhelmingly complex details of how things are represented or implemented.