{-# language MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-} module Satchmo.Integer.Difference where import Satchmo.Code import Satchmo.Numeric data Number a = Difference { top :: a, bot :: a } instance Decode m a Integer => Decode m ( Number a ) Integer where decode n = do t <- decode $ top n b <- decode $ bot n return $ t - b instance Constant a => Constant ( Number a ) where constant n = if n >= 0 then do t <- constant n b <- constant 0 return $ Difference { top = t, bot = b } else do t <- constant 0 b <- constant $ negate n return $ Difference { top = t, bot = b } instance Create a => Create ( Number a ) where create bits = do t <- create bits b <- create bits return $ Difference { top = t, bot = b } instance Numeric a => Numeric ( Number a ) where equal a b = do t <- plus ( top a ) ( bot b ) b <- plus ( bot a ) ( top b ) equal t b greater_equal a b = do t <- plus ( top a ) ( bot b ) b <- plus ( bot a ) ( top b ) greater_equal t b plus a b = do t <- plus ( top a ) ( top b ) b <- plus ( bot a ) ( bot b ) return $ Difference { top = t, bot = b } minus a b = do t <- plus ( top a ) ( bot b ) b <- plus ( bot a ) ( top b ) return $ Difference { top = t, bot = b } times a b = do tt <- times ( top a ) ( top b ) bb <- times ( bot a ) ( bot b ) t <- plus tt bb tb <- times ( top a ) ( bot b ) bt <- times ( bot a ) ( top b ) b <- plus tb bt return $ Difference { top = t, bot = b }