16 people like it.

Starbucks

Simple DSL for describing cups of Starbucks coffee and computing prices (in dollars).

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
module Starbucks

type size = Tall | Grande | Venti
type drink = Latte | Cappuccino | Mocha | Americano
type extra = Shot | Syrup

type Cup = { Size:size; Drink:drink; Extras:extra list } with
    static member (+) (cup:Cup,extra:extra) =
        { cup with Extras = extra :: cup.Extras }
    static member Of size drink =
        { Size=size; Drink=drink; Extras=[] }
    
let Price (cup:Cup) =
    let tall, grande, venti = 
        match cup.Drink with
        | Latte      -> 2.69, 3.19, 3.49
        | Cappuccino -> 2.69, 3.19, 3.49
        | Mocha      -> 2.99, 3.49, 3.79
        | Americano  -> 1.89, 2.19, 2.59
    let basePrice =
        match cup.Size with
        | Tall -> tall 
        | Grande -> grande
        | Venti -> venti
    let extras =
        cup.Extras |> List.sumBy (function
            | Shot -> 0.59
            | Syrup -> 0.39
        )
    basePrice + extras

let myCup = Cup.Of Venti Latte + Syrup
let price = Price myCup
module Starbucks
type size =
  | Tall
  | Grande
  | Venti

Full name: Starbucks.size
union case size.Tall: size
union case size.Grande: size
union case size.Venti: size
type drink =
  | Latte
  | Cappuccino
  | Mocha
  | Americano

Full name: Starbucks.drink
union case drink.Latte: drink
union case drink.Cappuccino: drink
union case drink.Mocha: drink
union case drink.Americano: drink
type extra =
  | Shot
  | Syrup

Full name: Starbucks.extra
union case extra.Shot: extra
union case extra.Syrup: extra
type Cup =
  {Size: size;
   Drink: drink;
   Extras: extra list;}
  static member Of : size:size -> drink:drink -> Cup
  static member ( + ) : cup:Cup * extra:extra -> Cup

Full name: Starbucks.Cup
Cup.Size: size
Cup.Drink: drink
Cup.Extras: extra list
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val cup : Cup
Multiple items
val extra : extra

--------------------
type extra =
  | Shot
  | Syrup

Full name: Starbucks.extra
static member Cup.Of : size:size -> drink:drink -> Cup

Full name: Starbucks.Cup.Of
Multiple items
val size : size

--------------------
type size =
  | Tall
  | Grande
  | Venti

Full name: Starbucks.size
Multiple items
val drink : drink

--------------------
type drink =
  | Latte
  | Cappuccino
  | Mocha
  | Americano

Full name: Starbucks.drink
val Price : cup:Cup -> float

Full name: Starbucks.Price
val tall : float
val grande : float
val venti : float
val basePrice : float
val extras : float
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sumBy
val myCup : Cup

Full name: Starbucks.myCup
static member Cup.Of : size:size -> drink:drink -> Cup
val price : float

Full name: Starbucks.price
Raw view Test code New version

More information

Link:http://fssnip.net/9w
Posted:13 years ago
Author:Phillip Trelford
Tags: dsl