-
Notifications
You must be signed in to change notification settings - Fork 0
/
wrongjar.hs
73 lines (56 loc) · 1.78 KB
/
wrongjar.hs
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
module WrongJar(
WrongJar,
empty,
isEmpty,
add,
total,
wrong,
runWrong
) where
import Control.Monad.Writer
import Data.Monoid
import Text.Printf
data Wrong = Wrong { getPerson :: String, getWrong :: String, getMoney :: Float }
deriving (Eq, Show)
newtype WrongJar = WrongJar { getJar :: [Wrong] }
deriving (Eq, Show)
empty :: WrongJar
empty = WrongJar []
isEmpty = (== empty)
add :: WrongJar -> String -> String -> Float -> WrongJar
add jar person wrong money =
let w = Wrong person wrong money
in WrongJar (w:getJar jar)
singleton :: String -> String -> Float -> WrongJar
singleton = add empty
merge :: WrongJar -> WrongJar -> WrongJar
merge a b = WrongJar (getJar a ++ getJar b)
summarise jar =
"The jar total is " ++ t ++ ". The most recent wrong was '" ++ w ++ "' committed by " ++ person ++ ", costing " ++ money ++ "."
where t = formatMoney $ total jar
lastWrong = last $ getJar jar
w = getWrong lastWrong
person = getPerson lastWrong
money = formatMoney $ getMoney lastWrong
formatMoney :: Float -> String
formatMoney m
| m < 1 = (show $ round (m * 100)) ++ "p"
| otherwise = "£" ++ printf "%.2f" m
total :: WrongJar -> Float
total (WrongJar []) = 0.0
total jar = sum . map getMoney . getJar $ jar
instance Monoid WrongJar where
mempty = empty
mappend = merge
newtype WrongWriter = Writer WrongJar
wrong person thing money = tell $ singleton person thing money
runWrong code =
let (result, jar) = runWriter code
in "Result is " ++ show result ++ "\n" ++ case isEmpty jar of
True -> "No wrongs committed."
False -> summarise jar
doStuff = do
wrong "rjh" "This is a wrong!" 0.3
wrong "sjw" "Again..." 0.1
return (3+4)
main = print $ runWrong doStuff