-- | Have you ever wondered why, when using a microwave, pressing \"60\" is the same as pressing \"100\"? Well wonder no longer! I, through epic trials and hardships, have tamed the vexacious wiles of that most enigmatic appliance. -- -- @ -- λ> let n = 200 :: Microwave -- λ> n -- 2:00 -- λ> n > 150 -- True -- λ> n > 170 -- False -- λ> n \`quotRem\` 7 -- (0:17,0:01) -- @ module Data.Microwave (Microwave) where newtype Microwave = Microwave {fromMicrowave :: Integer} instance Show Microwave where show (Microwave n) = let (mins, secs) = n `quotRem` 100 secs' = case (show secs) of [c] -> '0':[c] s -> s in show mins ++ ":" ++ secs' instance Read Microwave where readsPrec n s = let s' = filter (/= ':') s in map (\(n, r) -> (fixSecs n, r)) $ readsPrec n s' fixSecs n = let (mins, secs) = n `quotRem` 100 (carry, secs') = secs `quotRem` 60 in Microwave (100 * (mins + carry) + secs') -- turn display time into raw seconds normalize (Microwave n) = let (mins, secs) = n `quotRem` 100 in 60 * mins + secs -- turn raw seconds into display time denormalize n = let (mins, secs) = n `quotRem` 60 in Microwave (100 * mins + secs) instance Eq Microwave where n == m = normalize n == normalize m instance Ord Microwave where n `compare` m = normalize n `compare` normalize m instance Enum Microwave where fromEnum = fromInteger . normalize toEnum = denormalize . toInteger instance Num Microwave where fromInteger = fixSecs n + m = denormalize (normalize n + normalize m) n * m = denormalize (normalize n * normalize m) abs = Microwave . abs . fromMicrowave signum = Microwave . signum . fromMicrowave instance Real Microwave where toRational = toRational . normalize instance Integral Microwave where toInteger = normalize quotRem n m = let (q, r) = quotRem (normalize n) (normalize m) in (denormalize q, denormalize r)