Skip to content

Instantly share code, notes, and snippets.

@stesla
Created January 10, 2010 02:12
Show Gist options
  • Save stesla/273293 to your computer and use it in GitHub Desktop.
Save stesla/273293 to your computer and use it in GitHub Desktop.
module Money (
Money
, cents
, dollars
, amount
, fromCents
, fromDollars
, ($+$), ($+), (+$)
, ($-$), ($-), (-$)
, ($/$)
, ($*), (*$), ($/), (/$)
) where
import Control.Arrow (second)
newtype Money = Money { unM :: Integer } deriving (Eq, Ord)
instance Show Money where
show m = '$' : d ++ "." ++ c
where d = show (dollars m)
c | cents' < 10 = '0' : show cents'
| otherwise = show cents'
cents' = cents m
factor = 100
amount x = Money (dollars * factor + cents)
where (dollars, cents) = second (round . (* fromIntegral factor)) $ properFraction x
fromCents = Money
fromDollars = Money . (* factor)
cents = (`rem` factor) . unM
dollars = (`div` factor) . unM
a $+$ b = Money (unM a + unM b)
a $-$ b = Money (unM a - unM b)
a $/$ b = fromIntegral (unM a) / fromIntegral (unM b)
m $+ f = m $+$ amount f
m $- f = m $-$ amount f
(+$) = flip ($+)
(-$) = flip ($-)
scale fac m = Money (round cents')
where cents' = fromIntegral (unM m) * fac
(*$) = scale
($*) = flip (*$)
(/$) = scale . recip
($/) = flip (/$)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment