module Numeric.Decimal.Precision ( Precision(..) , FinitePrecision , P1 , P2 , P3 , P4 , P5 , P6 , P7 , P8 , P9 , P10 , P11, P12, P13, P14, P15, P16, P17, P18, P19, P20 , P21, P22, P23, P24, P25, P26, P27, P28, P29, P30 , P31, P32, P33, P34, P35, P36, P37, P38, P39, P40 , P41, P42, P43, P44, P45, P46, P47, P48, P49, P50 , P75, P100, P150, P200, P250, P300, P400, P500, P1000, P2000 , PPlus1, PPlus2, PPlus3, PPlus4, PPlus5, PPlus6, PPlus7, PPlus8, PPlus9 , PTimes2, PTimes10 , PInfinite ) where -- | Precision indicates the maximum number of significant decimal digits a -- number may have. class Precision p where -- | Return the precision of the argument, or 'Nothing' if the precision is infinite. precision :: p -> Maybe Int -- | A subclass of precisions that are finite class Precision p => FinitePrecision p -- | A precision of unlimited significant digits data PInfinite instance Precision PInfinite where precision _ = Nothing -- | A precision of 1 significant digit data P1 instance Precision P1 where precision _ = Just 1 instance FinitePrecision P1 -- | A precision of (@p@ + @q@) significant digits data PPlus p q instance (Precision p, Precision q) => Precision (PPlus p q) where precision pq = (+) <$> precision (p pq) <*> precision (q pq) where p :: PPlus p q -> p p = undefined q :: PPlus p q -> q q = undefined instance (FinitePrecision p, FinitePrecision q) => FinitePrecision (PPlus p q) -- | A precision of (@p@ × @q@) significant digits data PTimes p q instance (Precision p, Precision q) => Precision (PTimes p q) where precision pq = (*) <$> precision (p pq) <*> precision (q pq) where p :: PTimes p q -> p p = undefined q :: PTimes p q -> q q = undefined instance (FinitePrecision p, FinitePrecision q) => FinitePrecision (PTimes p q) type PPlus1 p = PPlus p P1 -- ^ A precision of (@p@ + 1) significant digits type PPlus2 p = PPlus p P2 -- ^ A precision of (@p@ + 2) significant digits type PPlus3 p = PPlus p P3 -- ^ A precision of (@p@ + 3) significant digits type PPlus4 p = PPlus p P4 -- ^ A precision of (@p@ + 4) significant digits type PPlus5 p = PPlus p P5 -- ^ A precision of (@p@ + 5) significant digits type PPlus6 p = PPlus p P6 -- ^ A precision of (@p@ + 6) significant digits type PPlus7 p = PPlus p P7 -- ^ A precision of (@p@ + 7) significant digits type PPlus8 p = PPlus p P8 -- ^ A precision of (@p@ + 8) significant digits type PPlus9 p = PPlus p P9 -- ^ A precision of (@p@ + 9) significant digits type PTimes2 = PTimes P2 type PTimes10 = PTimes P10 -- | A precision of 2 significant digits type P2 = PPlus1 P1 -- | A precision of 3 significant digits type P3 = PPlus1 P2 -- | Et cetera type P4 = PTimes2 P2 ; type P5 = PPlus1 P4 type P6 = PTimes2 P3 ; type P7 = PPlus1 P6 type P8 = PTimes2 P4 ; type P9 = PPlus1 P8 type P10 = PTimes2 P5 ; type P11 = PPlus1 P10 type P12 = PTimes2 P6 ; type P13 = PPlus1 P12 type P14 = PTimes2 P7 ; type P15 = PPlus1 P14 type P16 = PTimes2 P8 ; type P17 = PPlus1 P16 type P18 = PTimes2 P9 ; type P19 = PPlus1 P18 type P20 = PTimes2 P10; type P21 = PPlus1 P20 type P22 = PTimes2 P11; type P23 = PPlus1 P22 type P24 = PTimes2 P12; type P25 = PPlus1 P24 type P26 = PTimes2 P13; type P27 = PPlus1 P26 type P28 = PTimes2 P14; type P29 = PPlus1 P28 type P30 = PTimes2 P15; type P31 = PPlus1 P30 type P32 = PTimes2 P16; type P33 = PPlus1 P32 type P34 = PTimes2 P17; type P35 = PPlus1 P34 type P36 = PTimes2 P18; type P37 = PPlus1 P36 type P38 = PTimes2 P19; type P39 = PPlus1 P38 type P40 = PTimes2 P20; type P41 = PPlus1 P40 type P42 = PTimes2 P21; type P43 = PPlus1 P42 type P44 = PTimes2 P22; type P45 = PPlus1 P44 type P46 = PTimes2 P23; type P47 = PPlus1 P46 type P48 = PTimes2 P24; type P49 = PPlus1 P48 type P50 = PTimes2 P25 type P75 = PPlus5 (PTimes10 P7) type P100 = PTimes2 P50 type P150 = PTimes2 P75 type P200 = PTimes2 P100 type P250 = PTimes10 P25 type P300 = PTimes2 P150 type P400 = PTimes2 P200 type P500 = PTimes2 P250 type P1000 = PTimes2 P500 type P2000 = PTimes2 P1000