ushalow
[clean-tests.git] / old / afp / a12 / cashModel.icl
1 implementation module cashModel
2 /*
3 Pieter Koopman, Radboud University, 2017 - 2018
4 pieter@cs.ru.nl
5 Advanced programming
6
7 A simple state model for an automated cash register
8 */
9
10 import StdEnv, Data.GenEq
11
12 class euro a :: a -> Euro
13 instance euro Product where
14 euro Pizza = euro (4,99)
15 euro Beer = euro (0,65)
16 euro _ = euro 1
17
18 instance euro Int where euro e = {euro = e, cent = 0}
19 instance euro (Int, Int) where euro (e,c) = {euro = e, cent = c}
20 instance euro [e] | euro e where euro l = sum (map euro l)
21 instance euro Euro where euro e = e
22 instance + Euro where + x y = fromCents (toCents x + toCents y)
23 instance - Euro where - x y = fromCents (toCents x - toCents y)
24 instance zero Euro where zero = {euro = 0, cent = 0}
25 derive gEq Euro, Product
26 instance == Product where (==) p q = p === q
27 instance == Euro where (==) p q = p === q
28
29 instance ~ Euro where ~ e = {euro = ~e.euro, cent = ~e.cent}
30
31 toCents :: Euro -> Int
32 toCents e = if (e.euro < 0 || e.cent < 0) (~) id (abs e.euro*100 + abs e.cent)
33
34 fromCents :: Int -> Euro
35 fromCents c = if (c < 0) (~) id {euro=abs c / 100, cent=abs c rem 100}
36
37 model :: [Product] Action -> ([Product],[Euro])
38 model list (Add p) = ([p:list],[euro p])
39 model list (Rem p) | isMember p list
40 = (removeMember p list,[~ (euro p)])
41 = (list,[])
42 model list Pay = ([],[euro list])