{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Domain.Math.Data.MixedFraction
( MixedFraction, wholeNumber, fractionPart, numerator, denominator
) where
import qualified Data.Ratio as R
newtype MixedFraction = MF { unMF :: Rational }
deriving (Eq, Ord, Num, Fractional, Real, RealFrac)
instance Show MixedFraction where
show mf
| b == 0 = sign ++ show a
| a == 0 = sign ++ show b ++ "/" ++ show c
| otherwise = sign ++ show a ++ "[" ++ show b ++ "/" ++ show c ++ "]"
where
(a, b, c) = (wholeNumber mf, numerator mf, denominator mf)
sign = if mf < 0 then "-" else ""
wholeNumber :: MixedFraction -> Integer
wholeNumber = fst . properMF
fractionPart :: MixedFraction -> Rational
fractionPart = snd . properMF
numerator :: MixedFraction -> Integer
numerator = R.numerator . fractionPart
denominator :: MixedFraction -> Integer
denominator = R.denominator . fractionPart
properMF :: MixedFraction -> (Integer, Rational)
properMF = properFraction . abs . unMF