USD: monitary representation as a data type

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
module Data.Monetary.USD where

import Data.Monoid

import Control.Presentation          -- http://lpaste.net/588030780018524160
import Data.Monetary.Currency        -- http://lpaste.net/3442250682395000832

-- Spraken dollars, mang!

data USD = USD Rational deriving Eq

-- one line of declaration followed by HOW many lines of instantiation?

instance Ord USD where USD x <= USD y = x <= y
instance Show USD where show (USD x) = '$':laxmi x
instance Read USD where readsPrec _ ('$':val) = [(mknMoney USD val, "")]
instance Raw USD where rep (USD x) = laxmi x

instance Currency USD where
   value (USD x) = x     -- so Price-types are copointed ...

instance Num USD where
   d1 - d2 = USD $ value d1 - value d2
   negate dollar = USD $ 0.0 - value dollar
   d1 + d2 = USD $ value d1 + value d2
   d1 * d2 = USD $ value d1 * value d2
   abs dollar = USD $ abs (value dollar)
   signum dollar = USD $ signum (value dollar)
   fromInteger x = USD (fromInteger x)

instance Fractional USD where
   d1 / d2 = USD $ value d1 / value d2
   fromRational = USD

instance Monoid USD where
   mempty = USD 0
   (USD a) `mappend` (USD b) = USD $ a + b
-- because when you mappend dollars they are summed.