module FNWIvending import ESMVizTool import StdMisc Start :: *World -> *World Start world = esmVizTool FNWIvendingESM world :: State = { products :: [Product], choice :: Int, money :: Int} :: Input = Coin Coin | But Digit | ButOK | ButRst | GoToErrorState :: Product = { id :: Int, descr :: String, price :: Int } :: Output = Yield String | Return [Coin] | Message String :: Digit = D Int // numbers 0..9 :: Coin = C Int // 5, 10, 20, 50, 100, 200 cents derive class iTask State, Input, Product, Output, Digit, Coin //derive gEq State, Input, Product, Output // from derive class iTask derive ggen State, Input, Product, Output ggen{|Coin|} _ _ = map C [5,10,20,50,100,200] ggen{|Digit|} _ _ = map D [0..9] derive genShow State, Input, Product, Output genShow{|Digit|} s p (D i) c = [toString i:c] genShow{|Coin|} s p (C i) c = [toString i:c] instance render State where render {choice,money} = toHtmlString (toString choice + " " + toString (toReal money/100.0)) instance render Input where render i = show1 i instance render Output where render (Yield s) = s render (Return l) = show1 l render (Message m) = m derive bimap [] instance == State where (==) s t = s === t state0 :: State state0 = {products = products, choice = 0, money = 0} products = [{id = 53, descr = "Harlekijntjes", price = 155} ,{id = 54, descr = "Autodrop", price = 155} ,{id = 72, descr = "Mars", price = 140} ,{id = 31, descr = "Paprika chips", price = 120} ] FNWIvendingESM :: ESM State Input Output FNWIvendingESM = { s_0 =state0, d_F = fnwiSpec, out = \s i.[[],[Message "??"]], pred = \_.[] } fnwiSpec :: State Input -> [Trans Output State] fnwiSpec st i | st.choice < 0 = [] // to test the tool fnwiSpec st (Coin (C c)) # money = st.money + c = [Pt [] {st & money = money}] fnwiSpec st (But (D i)) | st.choice == 0 && not (isEmpty [p \\ p <- st.products | (p.id / 10) == i]) = [Pt [Message (toString i)] {st & choice = i}] # choice = 10 * st.choice + i = case [p \\ p <- st.products | p.id == choice] of [p] = [Pt [Message p.descr] {st & choice = choice}] = [] fnwiSpec st GoToErrorState = [Pt [] {st & choice = -1, money = 0}] // to test the tool fnwiSpec st ButRst = [Pt [Return [C st.money]] {st & choice = 0, money = 0}] fnwiSpec st ButOK = case [p \\ p <- st.products | p.id == st.choice && p.price <= st.money] of [p] # money = st.money - p.price = [Pt [Yield p.descr: if (money == 0) [] [Return [C money]]] {st & choice = 0, money = 0} ,Ft \out. case out of [Message m] = [{st & choice = 0}]; = []] [] = [Pt [] st] _ = [] fnwiSpec st input = []