content: {-  Starbucks  
   -  
   -  Simple DSL for describing cups of Starbucks coffee and computing prices (in dollars). 
   -  Example taken from: http://www.fssnip.net/9w 
   -
  -}
  
  
  data Size  = Tall | Grande | Venti
              deriving (Eq, Enum, Read, Show, Ord)
   
  data Drink = Latte | Cappuccino | Mocha | Americano            
              deriving (Eq, Enum, Read, Show, Ord)
  
  data Extra = Shot | Syrup
              deriving (Eq, Enum, Read, Show, Ord)
  
  data Cup = Cup {
                  cupDrink :: Drink,
                  cupSize  :: Size,
                  cupExtra :: [Extra]         
                 }
                 deriving(Eq, Show, Read)
  
  {-
   -                  Table in the format:
   -                 -------------------
   -                  tall, grande, venti 
   -    Latte         p00   p01     p02
   -    Cappuccino    p10   p11     p12
   -    Mocha         p20   p21     p22
   -    Amaericano    p30   p31     p32
   -}
  
  table = [
      [2.69, 3.19, 3.49],
      [2.69, 3.19, 3.49],
      [2.99, 3.49, 3.79],
      [1.89, 2.19, 2.59]
      ]    
  
  
  extraPrice :: Extra -> Double
  extraPrice Syrup = 0.59
  extraPrice Shot  = 0.39
  
  priceOfcup cup =  baseprice + extraprice
              where
              drinkrow = table !!  fromEnum  (cupDrink cup)
              baseprice   = drinkrow !!  fromEnum  (cupSize cup)
              extraprice = sum $ map extraPrice (cupExtra cup)
              
  
  
  {- Constructor of Cup -}
  cupOf drink size extra = Cup { 
                               cupSize = size, 
                               cupDrink = drink, 
                               cupExtra = extra}
  
  drink_options = [ Latte, Cappuccino, Mocha, Americano]
  size_options  = [ Tall, Grande, Venti]  
  extra_options = [[], [Shot], [Syrup], [Shot, Syrup]]
  
  cup_combinations =  
              [ cupOf drink size extra | drink <- drink_options, size <- size_options, extra <- extra_options]
  
  
  
  
  