F#: Revisiting the Vending Machine (again)

I really do enjoy the Vending Machine kata. I decided on the late night to revisit it.

module TempImpl

(*Types*)
type Product = Gum     | Chips | Soda
type Coin =    Quarter | Dime  | Nickel

type Change =  Change of Coin list

type Transaction =
    | Purchased  of Product * Change
    | Required   of decimal
    | OutOfStock of Product

(*Functions*)
let priceOf = function
              | Gum   -> 0.25m
              | Chips -> 0.50m
              | Soda  -> 1.00m

let valueOf = function
              | Quarter -> 0.25m
              | Dime    -> 0.10m
              | Nickel  -> 0.05m

let balanceOf coins =
    (0.0m , coins) 
    ||> List.fold (fun balance coin -> balance + (valueOf coin))
 
let remaining balance product = (priceOf product) - balance
 
let rec getChange balance change =
     
    let rec get remaining change =

        if remaining >= valueOf Quarter
        then get (remaining - valueOf Quarter) (Quarter::change)
 
        elif remaining >= valueOf Dime
        then get (remaining - valueOf Dime) (Dime::change)
 
        elif remaining >= valueOf Nickel
        then get (remaining - valueOf Nickel) (Nickel::change)
 
        else change
 
    get balance []


let select product deposited products =

    if not (products |> List.contains product)
    then OutOfStock product

    elif balanceOf deposited >= priceOf product
    then Purchased (product , Change <| getChange (balanceOf deposited - priceOf product) [])
    else Required (priceOf product - balanceOf deposited)

(*Client*)
let products = [ Gum ; Chips ; Soda ]
               |> select Gum [Quarter; 
                              Quarter; 
                              Quarter; 
                              Quarter]

Here’s the output:

val products : Transaction =
  Purchased (Gum,Change [Quarter; Quarter; Quarter])
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: