formatn 0.2.2 → 0.3.0
raw patch · 2 files changed
+177/−107 lines, 2 filesdep ~QuickCheckdep ~containersPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: QuickCheck, containers
API changes (from Hackage documentation)
+ Data.FormatN: [cutRightZeros] :: FormatN -> Bool
+ Data.FormatN: [maxDistinguishIterations] :: FormatN -> Int
+ Data.FormatN: decSigFig :: Int -> SigFig -> Maybe SigFig
+ Data.FormatN: decSigFigs :: [SigFig] -> [SigFig]
+ Data.FormatN: formatsSF :: Maybe Int -> [Double] -> [SigFig]
+ Data.FormatN: isZero :: SigFig -> Bool
+ Data.FormatN: lpads :: [Text] -> [Text]
- Data.FormatN: FormatN :: FStyle -> Maybe Int -> Bool -> FormatN
+ Data.FormatN: FormatN :: FStyle -> Maybe Int -> Int -> Bool -> Bool -> FormatN
- Data.FormatN: distinguish :: Int -> Bool -> (Double -> FormatStyle) -> Maybe Int -> [Double] -> [Text]
+ Data.FormatN: distinguish :: Int -> Bool -> Bool -> (Double -> FormatStyle) -> Maybe Int -> [Double] -> [Text]
- Data.FormatN: formatNs :: Int -> FormatN -> [Double] -> [Text]
+ Data.FormatN: formatNs :: FormatN -> [Double] -> [Text]
- Data.FormatN: formats :: Bool -> (Double -> FormatStyle) -> Maybe Int -> [Double] -> [Text]
+ Data.FormatN: formats :: Bool -> Bool -> (Double -> FormatStyle) -> Maybe Int -> [Double] -> [Text]
Files
- formatn.cabal +6/−6
- src/Data/FormatN.hs +171/−101
formatn.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: formatn-version: 0.2.2+version: 0.3.0 synopsis: Formatting of doubles. description: This package provides support for number formatting styles, especially styles involving significant figure calculations.@@ -34,12 +34,12 @@ -Wincomplete-uni-patterns -Wredundant-constraints build-depends:- , base >=4.7 && <5- , containers ^>=0.6- , QuickCheck- , text >=1.2 && <2.1+ , base >= 4.7 && < 5+ , containers >= 0.6 && < 0.7+ , text >= 1.2 && < 2.1+ -- just for cabal-docspec --check-properties+ , QuickCheck >= 2.14.2 && < 2.15 - -- just for cabal-docspec --check-properties exposed-modules: Data.FormatN other-modules: default-language: Haskell2010
src/Data/FormatN.hs view
@@ -4,7 +4,11 @@ {-# LANGUAGE StrictData #-} {-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use =<<" #-}+ -- | Text formatting of 'Double's. -- -- In particular, the library provides functionality to calculate and display a fixed number of <https://en.wikipedia.org/wiki/Significant_figures significant figures> for a variety of different number formatting styles.@@ -34,9 +38,11 @@ SigFigSign (..), toSigFig, fromSigFig,+ isZero, incSigFig,+ decSigFig, - -- * specific formatters+ -- * Format Styles FormatStyle (..), precStyle, commaPrecStyle,@@ -52,7 +58,7 @@ percentSF, formatSF, - -- * specific Double formatters+ -- * Double formatters format, formatOrShow, fixed,@@ -65,9 +71,12 @@ dollar, percent, - -- * list modifiers+ -- * List Modifiers majorityStyle, formats,+ formatsSF,+ decSigFigs,+ lpads, distinguish, -- * FormatN@@ -95,30 +104,28 @@ -- $setup -- >>> import Data.FormatN -- >>> xs = [(-1),0,1,1.01,1.02,1.1,1.2]--- -- >>> fixed (Just 2) <$> xs -- ["-1.00","0.00","1.00","1.01","1.02","1.10","1.20"]--- -- >>> decimal (Just 2) <$> xs -- ["-1.0","0.0","1.0","1.0","1.0","1.1","1.2"]--- -- >>> decimal (Just 3) . (1e-3*) <$> xs -- ["-0.00100","0.00","0.00100","0.00101","0.00102","0.00110","0.00120"]--- -- >>> comma (Just 3) . (1e3*) <$> xs -- ["-1,000","0.00","1,000","1,010","1,020","1,100","1,200"] ----- Using significant figures actually changes numbers - numbers that were slightly different end up being (and looking like) the same. 'distinguish' increases the number of significant figures to get around this.+-- 'formats' is useful when you want a consistent textual style across a list of numbers: ----- >>> formats False (const CommaStyle) (Just 2) $ (1e3*) <$> xs--- ["-1,000","0","1,000","1,000","1,000","1,100","1,200"]+-- >>> formats True False (const DecimalStyle) (Just 2) $ (1e-3*) <$> xs+-- ["-0.0010"," 0.0000"," 0.0010"," 0.0010"," 0.0010"," 0.0011"," 0.0012"] ----- >>> distinguish 4 False (const CommaStyle) (Just 2) $ (1e3*) <$> xs--- ["-1,000","0","1,000","1,010","1,020","1,100","1,200"]+-- Using significant figures actually changes numbers - numbers that were slightly different end up being (and looking like) the same. 'distinguish' increases the number of significant figures to compensate for this effect.+--+-- >>> distinguish 4 True False (const DecimalStyle) (Just 2) xs+-- ["-1.00"," 0.00"," 1.00"," 1.01"," 1.02"," 1.10"," 1.20"] -- | Decomposition of a Double into the components that are needed to determine significant figure formatting. ----- eliding type changes, the relationship between a Double and a SigFig is:+-- Eliding type changes, the relationship between a Double and a SigFig is: -- -- \[ -- x == sign * figures * 10^{exponent}@@ -139,19 +146,38 @@ sfsign :: SigFigSign -> String sfsign s = bool "" "-" (s == SigFigNeg) +-- | Note that zero can still be represented in a SigFig way, so that we can distinguish between something that starts off as zero, and something that ends up as zero via rounding.+--+-- >>> isZero (SigFig SigFigPos 0 (-3))+-- True+isZero :: SigFig -> Bool+isZero (SigFig _ i _) = i == 0+ -- | convert from a Double to a 'SigFig' -- -- >>> toSigFig (Just 2) 1234 -- SigFig {sfSign = SigFigPos, sfFigures = 12, sfExponent = 2} --+-- > toSigFig Nothing . fromSigFig <==> id+-- > toSigFig (Just x) . fromSigFig . toSigFig (Just x) <==> toSigFig (Just x)+-- -- prop> \x -> let (SigFig s fs e) = toSigFig Nothing x in let x' = ((if (s==SigFigNeg) then (-1.0) else 1.0) * fromIntegral fs * 10.0**fromIntegral e) in (x==0 || abs (x/x'-1) < 1e-6)+--+-- Checks for a valid number of significant figures and turns it off on a silly number.+--+-- >>> toSigFig Nothing 1234+-- SigFig {sfSign = SigFigPos, sfFigures = 1234, sfExponent = 0}+--+-- >>> toSigFig (Just (-3)) 1234+-- SigFig {sfSign = SigFigPos, sfFigures = 1234, sfExponent = 0} toSigFig :: Maybe Int -> Double -> SigFig toSigFig n x = SigFig s fs' expo' where+ n' = maybe Nothing (\sf -> bool (Just sf) Nothing (sf < 1)) n (s, (floatfs, floate)) = bool (SigFigPos, floatToDigits 10 x) (SigFigNeg, floatToDigits 10 (-x)) (x < 0) -- floatToDigits 10 0 == ([0],0) floatToDigits 10 1 == ([1],1) floate' = bool floate (floate + 1) (x == 0)- nsig = fromMaybe (length floatfs) n+ nsig = fromMaybe (length floatfs) n' -- pad with extra zeros if less figures than requested (floatfs', e) = bool@@ -181,9 +207,26 @@ fromSigFig (SigFig s fs e) = bool 1 (-1) (s == SigFigNeg) * fromIntegral fs * 10 ** fromIntegral e -- | increase significant figures+--+-- >>> incSigFig 1 (SigFig SigFigPos 1 0)+-- SigFig {sfSign = SigFigPos, sfFigures = 10, sfExponent = -1} incSigFig :: Int -> SigFig -> SigFig incSigFig n (SigFig s fs e) = SigFig s (fs * (10 ^ max 0 n)) (e - n) +-- | decrease significant figures, if possible.+--+-- >>> decSigFig 1 (SigFig SigFigPos 100 0)+-- Just (SigFig {sfSign = SigFigPos, sfFigures = 10, sfExponent = 1})+--+-- >>> decSigFig 1 (SigFig SigFigPos 123 0)+-- Nothing+decSigFig :: Int -> SigFig -> Maybe SigFig+decSigFig n (SigFig s fs e) =+ bool+ Nothing+ (Just (SigFig s (fs `div` (10 ^ n)) (e + n)))+ (fs `mod` (10 ^ n) == 0 && n > 0)+ -- The natural exponent to format with eSF :: SigFig -> Int eSF (SigFig _ fs e) = e + length (show fs) - 1@@ -194,22 +237,20 @@ -- | expt format for a SigFig exptSF :: SigFig -> Text-exptSF (SigFig s i e) = pack $ sfsign s <> bool (i'' <> "e" <> show e') "0" (i == 0)+exptSF (SigFig s i e) = pack $ sfsign s <> sfTextDot <> "e" <> show eText where- i''- | length i' == 1 = i'- | otherwise = take 1 i' <> "." <> drop 1 i'- i' = show i- e' = e + length i' - 1+ sfTextDot+ | length sfText == 1 = sfText+ | otherwise = take 1 sfText <> "." <> drop 1 sfText+ sfText = bool (show i) (replicate (max 1 (1 - e)) '0') (i == 0)+ eText = e + length sfText - 1 -- | expt format for a SigFig, with an exponent override -- -- >>> exptSFWith (Just 1) (toSigFig (Just 1) 1) -- "0.1e1"--- -- >>> exptSFWith (Just 0) (toSigFig (Just 1) 1) -- "1e0"--- -- >>> exptSFWith (Just (-1)) (toSigFig (Just 1) 1) -- "10e-1" exptSFWith :: Maybe Int -> SigFig -> Text@@ -264,7 +305,6 @@ -- -- >>> fixed (Just 2) 100 -- "100.00"--- -- >>> fixed (Just 2) 0.001 -- "0.00" fixed :: Maybe Int -> Double -> Text@@ -274,17 +314,12 @@ -- -- >>> expt Nothing 1245 -- "1.245e3"--- -- >>> expt (Just 3) 1245 -- "1.24e3"--- -- >>> expt (Just 3) 0.1245 -- "1.24e-1"--- -- >>> expt (Just 2) 0--- "0"------ If we wanted to have expt (Just 2) 0 == "0.0e0" then SigFig would need refactoring as it doesn't remember the desired significant figure number except through the Integer mantissa, which disappears if the number happens to be zero.+-- "0.0e0" expt :: Maybe Int -> Double -> Text expt n x = exptSF (toSigFig n x) @@ -292,7 +327,6 @@ -- -- >>> exptWith (Just 2) Nothing 1245 -- "12.45e2"--- -- >>> exptWith (Just 6) (Just 3) 1245 -- "0.00124e6" exptWith :: Maybe Int -> Maybe Int -> Double -> Text@@ -302,10 +336,8 @@ -- -- >>> decimal Nothing 1.2345e-2 -- "0.012345"--- -- >>> decimal (Just 2) 0.012345 -- "0.012"--- -- >>> decimal (Just 2) 12345 -- "12000" decimal :: Maybe Int -> Double -> Text@@ -322,7 +354,6 @@ -- -- >>> percent commaSF (Just 3) 0.1234 -- "12.3%"--- -- >>> percent decimalSF (Just 1) 0.1234 -- "10%" percent :: (SigFig -> Text) -> Maybe Int -> Double -> Text@@ -332,7 +363,6 @@ -- -- >>> dollar commaSF (Just 3) 1234 -- "$1,230"--- -- >>> dollar (fixedSF (Just 2)) (Just 2) 0.01234 -- "$0.01" dollar :: (SigFig -> Text) -> Maybe Int -> Double -> Text@@ -342,9 +372,7 @@ data FormatStyle = -- | 1000 1 0.001 DecimalStyle- | -- | The parameter represents the exponent to format to with Nothing meaning:- --- -- 1e3 1e1 1e-3+ | -- | 1e3 1e0 1e-3 ExponentStyle (Maybe Int) | -- | 1,000 1 0.001 CommaStyle@@ -356,7 +384,7 @@ DollarStyle deriving (Show, Eq, Ord) --- | DecimalStyle between 0.001 and 1000000 and ExponentStyle outside this range.+-- | DecimalStyle between 0.001 and a million and ExponentStyle outside this range. precStyle :: Double -> FormatStyle precStyle x | x == 0 = DecimalStyle@@ -364,7 +392,7 @@ | abs x > 1e6 = ExponentStyle (Just (eSF (toSigFig Nothing x))) | otherwise = DecimalStyle --- | CommaStyle above 1,000 but below a million, DecimalStyle between 0.001 and a million and ExponentStyle outside this range.+-- | CommaStyle above a thousand but below a million, DecimalStyle between 0.001 and a thousand and ExponentStyle outside this range. commaPrecStyle :: Double -> FormatStyle commaPrecStyle x | x == 0 = CommaStyle@@ -385,13 +413,12 @@ | FSNone deriving (Show, Eq, Ord) --- | Compute the majority FormatStyle so a list of numbers can all have the same formatting+-- | Compute the majority (modal) FormatStyle so a list of numbers can all have the same formatting ----- Also equalises the exponent to majority for exponent style.+-- Also equalises the exponent to the majority for exponent style. -- -- >>> commaPrecStyle <$> [0,5e6,1e7,2e7] -- [CommaStyle,ExponentStyle (Just 6),ExponentStyle (Just 7),ExponentStyle (Just 7)]--- -- >>> majorityStyle commaPrecStyle [0,5e6,1e7,2e7] -- ExponentStyle (Just 7) majorityStyle :: (Double -> FormatStyle) -> [Double] -> FormatStyle@@ -426,7 +453,6 @@ -- -- >>> formatSF CommaStyle (toSigFig (Just 2) 1234) -- "1,200"--- -- >>> formatSF CommaStyle (SigFig SigFigPos 0 1) -- "0" -- >>> formatSF CommaStyle (SigFig SigFigPos 0 (-1))@@ -444,16 +470,12 @@ -- -- >>> prec (Just 2) 0.00234 -- "0.0023"--- -- >>> prec (Just 2) 0.000023 -- "2.3e-5"--- -- >>> prec (Just 2) 123 -- "120"--- -- >>> prec (Just 2) 123456 -- "120000"--- -- >>> prec (Just 2) 1234567 -- "1.2e6" prec :: Maybe Int -> Double -> Text@@ -463,40 +485,42 @@ -- -- >>> commaPrec (Just 3) 1234 -- "1,230"--- -- >>> commaPrec (Just 3) 1234567 -- "1.23e6" commaPrec :: Maybe Int -> Double -> Text commaPrec n x = format (commaPrecStyle x) n x --- | Consistently format a list of numbers+-- | Consistently format a list of numbers,using the minimum number of decimal places or minimum exponent. ----- >>> formats True precStyle (Just 1) [0,0.5,1,2]+-- >>> formats True True precStyle (Just 1) [0,0.5,1,2] -- ["0.0","0.5","1.0","2.0"] ----- >>> formats False precStyle (Just 1) $ ((-1)*) <$> [0,0.5,1,2]--- ["0.0","-0.5","-1.0","-2.0"]+-- Note how the presence of 0.5 in the example above changes the format of all numbers. Without it: ----- >>> formats True commaPrecStyle (Just 1) $ ((-1000)*) <$> [0,0.5,1,2]--- [" 0"," -500","-1,000","-2,000"]+-- >>> formats True True precStyle (Just 1) [0,1,2]+-- ["0","1","2"] ----- >>> formats True commaPrecStyle (Just 1) $ ((1e6)*) <$> [0,0.5,1,2]+-- >>> formats False True precStyle (Just 1) $ ((-1)*) <$> [0,0.5,1,2]+-- ["0.0","-0.5","-1.0","-2.0"]+-- >>> formats True True commaPrecStyle (Just 1) $ ((-1000)*) <$> [0,0.5,1,2]+-- [" 0"," -500","-1,000","-2,000"]+-- >>> formats True True commaPrecStyle (Just 1) $ ((1e6)*) <$> [0,0.5,1,2] -- [" 0"," 500,000","1,000,000","2,000,000"]------ >>> formats True commaPrecStyle (Just 1) $ ((1e6)*) <$> [0.9,2,3]+-- >>> formats True True commaPrecStyle (Just 1) $ ((1e6)*) <$> [0.9,2,3] -- ["0.9e6","2.0e6","3.0e6"]------ >>> formats True commaPrecStyle (Just 1) $ ((1e-6)*) <$> [0,0.5,1,2]+-- >>> formats True True commaPrecStyle (Just 1) $ ((1e-6)*) <$> [0,0.5,1,2] -- ["0.0e-6","0.5e-6","1.0e-6","2.0e-6"]------ >>> formats True commaPrecStyle (Just 1) $ ((1e-3)*) <$> [0,0.5,1,2]+-- >>> formats True True commaPrecStyle (Just 1) $ ((1e-3)*) <$> [0,0.5,1,2] -- ["0.0000","0.0005","0.0010","0.0020"]------ >>> formats True (const (ExponentStyle Nothing)) (Just 2) [0..4]+-- >>> formats True False (const (ExponentStyle Nothing)) (Just 2) [0..4] -- ["0.0e0","1.0e0","2.0e0","3.0e0","4.0e0"]+-- >>> formats True True (const (ExponentStyle Nothing)) (Just 2) [0..4]+-- ["0e0","1e0","2e0","3e0","4e0"] formats :: -- | left pad to the largest text length Bool ->+ -- | Try and reduce excess right-hand zeros+ Bool -> -- | style (Double -> FormatStyle) -> -- | significant figures requested@@ -504,14 +528,44 @@ -- | list of numbers [Double] -> [Text]-formats lpad s n0 xs = bool fsigs (lpads fsigs) lpad+formats lpad rcut s n0 xs =+ formatsFromSF lpad s $+ bool id decSigFigs rcut (formatsSF n0 xs)++-- | Consistently convert a list of numbers to 'SigFig's, using the minimum natural exponent of the list.+formatsSF ::+ -- | significant figures requested+ Maybe Int ->+ -- | list of numbers+ [Double] ->+ [SigFig]+formatsSF n0 xs = sigs' where sigs = toSigFig n0 <$> xs- minexp = minimum (sfExponent <$> filter (\x -> sfFigures x /= 0) sigs)- sigs' = (\x -> bool (incSigFig (sfExponent x - minexp) x) (x {sfExponent = min 1 minexp}) (sfFigures x == 0)) <$> sigs- maj = majorityStyle s (fromSigFig <$> sigs')- fsigs = formatSF maj <$> sigs'+ minexp = minimum (sfExponent <$> filter (not . isZero) sigs)+ sigs' = (\x -> bool (incSigFig (sfExponent x - minexp) x) (SigFig SigFigPos 0 minexp) (isZero x)) <$> sigs +formatsFromSF ::+ -- | left pad to the largest text length+ Bool ->+ -- | style+ (Double -> FormatStyle) ->+ -- | list of numbers+ [SigFig] ->+ [Text]+formatsFromSF lpad s sigs = bool fsigs (lpads fsigs) lpad+ where+ maj = majorityStyle s (fromSigFig <$> sigs)+ fsigs = formatSF maj <$> sigs++-- | Decrease the SigFig figure of a list of SigFigs without loss of precision, if possible. This has the effect of removing right zeros in decimal representations.+decSigFigs :: [SigFig] -> [SigFig]+decSigFigs xs = bool xs (decSigFigs xs') (all isJust decXs)+ where+ decXs = decSigFig 1 <$> xs+ xs' = catMaybes decXs++-- | Add spaces to the left of a text representation so that all elements have the same length. lpads :: [Text] -> [Text] lpads ts = (\x -> mconcat (replicate (maxl - Text.length x) " ") <> x) <$> ts where@@ -523,16 +577,32 @@ -- -- The difference between this and 'formats' can be seen in these examples: ----- >>> formats True commaPrecStyle (Just 2) [0,1,1.01,1.02,1.1,1.2]+-- >>> formats True True commaPrecStyle (Just 2) [0,1,1.01,1.02,1.1,1.2] -- ["0.0","1.0","1.0","1.0","1.1","1.2"]------ >>> distinguish 4 True commaPrecStyle (Just 2) [0,1,1.01,1.02,1.1,1.2]+-- >>> distinguish 4 True True commaPrecStyle (Just 2) [0,1,1.01,1.02,1.1,1.2] -- ["0.00","1.00","1.01","1.02","1.10","1.20"]+--+-- A common occurence is that significant figures being increased to enable textual uniqueness results in excess right zeros (after a decimal place). Consider:+--+-- >>> formats True False commaPrecStyle (Just 1) [0, 0.5, 1, 1.5, 2]+-- ["0.0","0.5","1.0","2.0","2.0"]+--+-- Note that formats seeks With 1.5 rounding up to 2, the distinguish algorithm will increase the number of sigfigs to 2:+--+-- >>> distinguish 4 True False commaPrecStyle (Just 1) [0, 0.5, 1, 1.5, 2]+-- ["0.00","0.50","1.00","1.50","2.00"]+--+-- The format can be simplified further by removing the excess right zeros from each formatted number:+--+-- >>> distinguish 4 True True commaPrecStyle (Just 2) [0, 0.5, 1, 1.5, 2]+-- ["0.0","0.5","1.0","1.5","2.0"] distinguish :: -- | maximum number of iterations Int -> -- | left pad to the largest text length Bool ->+ -- | try and reduce excess right zero pads+ Bool -> -- | style (Double -> FormatStyle) -> -- | significant figures requested@@ -540,60 +610,60 @@ -- | list of numbers [Double] -> [Text]-distinguish maxi pad f n xs =+distinguish maxi pad cutr f n xs = case n of- Nothing -> formats pad f Nothing xs- Just n0 -> loop n0 xs+ Nothing -> formats pad cutr f Nothing xs+ Just n0 -> loopSF n0 where- loop n' xs' =- let s = formats pad f (Just n') xs'- in bool (loop (1 + n') xs') s (s == nubOrd s || n' > maxi)+ loopSF n' = bool (loopSF (1 + n')) s (s == nubOrd s || n' > maxi)+ where+ s = formats pad cutr f (Just n') xs -- | Wrapper for the various formatting options. -- -- >>> defaultFormatN--- FormatN {fstyle = FSCommaPrec, sigFigs = Just 2, addLPad = True}-data FormatN = FormatN {fstyle :: FStyle, sigFigs :: Maybe Int, addLPad :: Bool} deriving (Eq, Show, Generic)+-- FormatN {fstyle = FSCommaPrec, sigFigs = Just 2, maxDistinguishIterations = 4, addLPad = True, cutRightZeros = True}+data FormatN = FormatN {fstyle :: FStyle, sigFigs :: Maybe Int, maxDistinguishIterations :: Int, addLPad :: Bool, cutRightZeros :: Bool} deriving (Eq, Show, Generic) -- | The official FormatN defaultFormatN :: FormatN-defaultFormatN = FormatN FSCommaPrec (Just 2) True+defaultFormatN = FormatN FSCommaPrec (Just 2) 4 True True -- | run a 'FormatN' -- -- >>> formatN defaultFormatN 1234 -- "1,200" formatN :: FormatN -> Double -> Text-formatN (FormatN FSDecimal sf _) x = format DecimalStyle sf x-formatN (FormatN (FSExponent n) sf _) x = format (ExponentStyle n) sf x-formatN (FormatN FSComma sf _) x = format CommaStyle sf x-formatN (FormatN (FSFixed n) sf _) x = format (FixedStyle n) sf x-formatN (FormatN FSPercent sf _) x = format PercentStyle sf x-formatN (FormatN FSDollar sf _) x = format DollarStyle sf x-formatN (FormatN FSPrec sf _) x = format (precStyle x) sf x-formatN (FormatN FSCommaPrec sf _) x = format (commaPrecStyle x) sf x-formatN (FormatN FSNone _ _) x = pack (show x)+formatN fn x = case fstyle fn of+ FSDecimal -> format DecimalStyle (sigFigs fn) x+ (FSExponent n) -> format (ExponentStyle n) (sigFigs fn) x+ FSComma -> format CommaStyle (sigFigs fn) x+ (FSFixed n) -> format (FixedStyle n) (sigFigs fn) x+ FSPercent -> format PercentStyle (sigFigs fn) x+ FSDollar -> format DollarStyle (sigFigs fn) x+ FSPrec -> format (precStyle x) (sigFigs fn) x+ FSCommaPrec -> format (commaPrecStyle x) (sigFigs fn) x+ FSNone -> pack (show x) -- | Consistently format a list of numbers via using 'distinguish'. ----- >>> formatNs 4 defaultFormatN [0,1,1.01,1.02,1.1,1.2]+-- >>> formatNs defaultFormatN [0,1,1.01,1.02,1.1,1.2] -- ["0.00","1.00","1.01","1.02","1.10","1.20"]-formatNs :: Int -> FormatN -> [Double] -> [Text]-formatNs maxi (FormatN FSDecimal sf pad) x = distinguish maxi pad (const DecimalStyle) sf x-formatNs maxi (FormatN (FSExponent n) sf pad) x = distinguish maxi pad (const (ExponentStyle n)) sf x-formatNs maxi (FormatN FSComma sf pad) x = distinguish maxi pad (const CommaStyle) sf x-formatNs maxi (FormatN (FSFixed n) sf pad) x = distinguish maxi pad (const (FixedStyle n)) sf x-formatNs maxi (FormatN FSPercent sf pad) x = distinguish maxi pad (const PercentStyle) sf x-formatNs maxi (FormatN FSDollar sf pad) x = distinguish maxi pad (const DollarStyle) sf x-formatNs maxi (FormatN FSPrec sf pad) x = distinguish maxi pad precStyle sf x-formatNs maxi (FormatN FSCommaPrec sf pad) x = distinguish maxi pad commaPrecStyle sf x-formatNs _ (FormatN FSNone _ pad) x = bool id lpads pad $ pack . show <$> x+formatNs :: FormatN -> [Double] -> [Text]+formatNs (FormatN FSDecimal sf maxi pad cutr) x = distinguish maxi pad cutr (const DecimalStyle) sf x+formatNs (FormatN (FSExponent n) sf maxi pad cutr) x = distinguish maxi pad cutr (const (ExponentStyle n)) sf x+formatNs (FormatN FSComma sf maxi pad cutr) x = distinguish maxi pad cutr (const CommaStyle) sf x+formatNs (FormatN (FSFixed n) sf maxi pad cutr) x = distinguish maxi pad cutr (const (FixedStyle n)) sf x+formatNs (FormatN FSPercent sf maxi pad cutr) x = distinguish maxi pad cutr (const PercentStyle) sf x+formatNs (FormatN FSDollar sf maxi pad cutr) x = distinguish maxi pad cutr (const DollarStyle) sf x+formatNs (FormatN FSPrec sf maxi pad cutr) x = distinguish maxi pad cutr precStyle sf x+formatNs (FormatN FSCommaPrec sf maxi pad cutr) x = distinguish maxi pad cutr commaPrecStyle sf x+formatNs (FormatN FSNone _ _ pad _) x = bool id lpads pad $ pack . show <$> x -- | Format with the shorter of show and a style. -- -- >>> format (ExponentStyle Nothing) Nothing 0 -- "0e0"--- -- >>> formatOrShow (ExponentStyle Nothing) Nothing 0 -- "0" formatOrShow :: FormatStyle -> Maybe Int -> Double -> Text