One of the more common design patterns used in object oriented languages like C# is the Composite Pattern. The main benefit of using this pattern is that it allows us to treat individual objects and composite of objects in the same way. In the UML below, the type Component is abstract and defines the operations (method1 and method2) which are implemented by the concrete types Leaf and Composite. The type Composite contains a collection of Component objects. Due to the fact that it inherits from Component we can write code that invokes method1 and method2 without knowing the specific type.

For example, suppose we work at a fast food chain and we'd like to write code for computing the price of fries, burger, coke or a combo meal. Following the composite pattern, we could create an abstract class called Product which has the GetPrice() method and then one class each for Burger, Fries, Coke and ComboMeal.
Component --- maps to --> Product
Leaf --- maps to --> Burger, Fries, Coke
Composite --- maps to ---> ComboMeal
Our C# code would look like
public abstract class Product
{
public abstract double GetPrice();
}
public class Fries : Product
{
public override double GetPrice()
{
return 1.0;
}
}
public class Burger : Product
{
public override double GetPrice()
{
return 5.0;
}
}
public class Coke : Product
{
public override double GetPrice()
{
return 2.0;
}
}
public class ComboMeal : Product
{
List<Product> _products = new List<Product>();
public void Add(Product p)
{
this._products.Add(p);
}
public override double GetPrice()
{
var sum = 0.0;
foreach (var p in _products)
sum += p.GetPrice();
return sum;
}
}
we can then write a helper method that Computes a price. This method does not need to know whether its computing the price of a single item (Fries, Burger ) or that of a combo meal.
public static double ComputePrice(Product p)
{
return p.GetPrice();
}
Suppose, someone ordered 1 fries and 1 Burger separately, our code will be,
var totalFriesAndBurger = ComputePrice(new Fries()) + ComputePrice(new Burger());
Now if another one ordered a Combo meal (Fries + Coke + Burger), our code will be
var combo = new ComboMeal();
combo.Add(new Fries());
combo.Add(new Burger());
combo.Add(new Coke());
var totalCombo = ComputePrice(combo);
That's it.
For our C# implementation (not counting the helper method ComputePrice() ), we have 5 classes and approximately 40 lines of code.
Now lets see how we can implement the same pattern in F#.
Knowing that the types Fries, Burger, Coke and ComboMeal are just different representations of the Product type, we can model this relationship cleanly in F# using discriminated unions. To represent the the combo meal, we make it into a tupleof 2 products. An item of this tuple can be a single product (Coke, Fries or Burger) or any combination (i.e a combo)
type Product =
| Fries of double
| Coke of double
| Burger of double
| Combo of Product * Product
And how about the GetPrice method, you'd ask? That's easy enough; F# allows us to add methods to union types. Implementing that, our code now looks like this. Notice the "with member w.GetPrice()" part?
type Product =
| Fries of double
| Coke of double
| Burger of double
| Combo of Product * Product
with
member w.GetPrice() =
match w with
| Fries(p) | Coke(p) | Burger(p)-> p
| Combo(p1,p2) -> p1.GetPrice() + p2.GetPrice()
Again, if someone ordered a combo meal our code will look like
let combomeal = Combo(fries, Combo(burger, coke))
Console.WriteLine("Combo meal Total = " + combomeal.GetPrice().ToString())
That's just cool isn't it? With F# we ony 1 Union type and about 10 lines of code