2 people like it.

Decorator Pattern with Object Expressions

A simple example of a decorator pattern using object expressions and the pipeline operator for a fluent interface

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
type Coffee =
  abstract member getCost: unit -> double
  abstract member getIngredients: unit -> string list
let SimpleCoffee = 
  { new Coffee with 
    member this.getCost() = 1.0
    member this.getIngredients() = ["Coffee"]
  }
let WithMilk(coffee:Coffee) =
  { new Coffee with 
    member this.getCost() = coffee.getCost() + 0.5
    member this.getIngredients() = "milk" :: coffee.getIngredients() }
let WithSyrup (syrup:string) (coffee:Coffee) =
  { new Coffee with 
    member this.getCost() = coffee.getCost() + 0.25
    member this.getIngredients() = syrup :: coffee.getIngredients() }

// Let's try it out
let myCoffee = WithMilk(SimpleCoffee)
// We can pipe them too
abstract member Coffee.getCost : unit -> double

Full name: Script.Coffee.getCost
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
Multiple items
val double : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.double

--------------------
type double = System.Double

Full name: Microsoft.FSharp.Core.double
abstract member Coffee.getIngredients : unit -> string list

Full name: Script.Coffee.getIngredients
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val SimpleCoffee : Coffee

Full name: Script.SimpleCoffee
type Coffee =
  interface
    abstract member getCost : unit -> double
    abstract member getIngredients : unit -> string list
  end

Full name: Script.Coffee
val this : Coffee
abstract member Coffee.getCost : unit -> double
abstract member Coffee.getIngredients : unit -> string list
val WithMilk : coffee:Coffee -> Coffee

Full name: Script.WithMilk
val coffee : Coffee
val WithSyrup : syrup:string -> coffee:Coffee -> Coffee

Full name: Script.WithSyrup
val syrup : string
val myCoffee : Coffee

Full name: Script.myCoffee
Raw view Test code New version

More information

Link:http://fssnip.net/oh
Posted:10 years ago
Author:Steve Goguen
Tags: patterns