{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TupleSections #-}
{-# OPTIONS_GHC -Wall #-}
module Data.FormatN
(
SigFig (..),
SigFigSign (..),
toSigFig,
fromSigFig,
incSigFig,
FormatStyle (..),
precStyle,
commaPrecStyle,
FStyle (..),
fixedSF,
exptSF,
exptSFWith,
decimalSF,
commaSF,
dollarSF,
percentSF,
formatSF,
format,
formatOrShow,
fixed,
expt,
exptWith,
decimal,
prec,
comma,
commaPrec,
dollar,
percent,
majorityStyle,
formats,
distinguish,
FormatN (..),
defaultFormatN,
formatN,
formatNs,
)
where
import Data.Bifunctor
import Data.Bool
import Data.Containers.ListUtils (nubOrd)
import Data.Foldable
import qualified Data.List as List
import qualified Data.Map.Strict as Map
import Data.Maybe
import Data.Ord
import Data.Text (Text, pack)
import qualified Data.Text as Text
import GHC.Generics hiding (prec)
import Numeric
import Prelude hiding (exponent)
data SigFig = SigFig
{
SigFig -> SigFigSign
sfSign :: SigFigSign,
SigFig -> Integer
sfFigures :: Integer,
SigFig -> Int
sfExponent :: Int
}
deriving (SigFig -> SigFig -> Bool
(SigFig -> SigFig -> Bool)
-> (SigFig -> SigFig -> Bool) -> Eq SigFig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SigFig -> SigFig -> Bool
$c/= :: SigFig -> SigFig -> Bool
== :: SigFig -> SigFig -> Bool
$c== :: SigFig -> SigFig -> Bool
Eq, Int -> SigFig -> ShowS
[SigFig] -> ShowS
SigFig -> String
(Int -> SigFig -> ShowS)
-> (SigFig -> String) -> ([SigFig] -> ShowS) -> Show SigFig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SigFig] -> ShowS
$cshowList :: [SigFig] -> ShowS
show :: SigFig -> String
$cshow :: SigFig -> String
showsPrec :: Int -> SigFig -> ShowS
$cshowsPrec :: Int -> SigFig -> ShowS
Show)
data SigFigSign = SigFigNeg | SigFigPos deriving (SigFigSign -> SigFigSign -> Bool
(SigFigSign -> SigFigSign -> Bool)
-> (SigFigSign -> SigFigSign -> Bool) -> Eq SigFigSign
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SigFigSign -> SigFigSign -> Bool
$c/= :: SigFigSign -> SigFigSign -> Bool
== :: SigFigSign -> SigFigSign -> Bool
$c== :: SigFigSign -> SigFigSign -> Bool
Eq, Int -> SigFigSign -> ShowS
[SigFigSign] -> ShowS
SigFigSign -> String
(Int -> SigFigSign -> ShowS)
-> (SigFigSign -> String)
-> ([SigFigSign] -> ShowS)
-> Show SigFigSign
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SigFigSign] -> ShowS
$cshowList :: [SigFigSign] -> ShowS
show :: SigFigSign -> String
$cshow :: SigFigSign -> String
showsPrec :: Int -> SigFigSign -> ShowS
$cshowsPrec :: Int -> SigFigSign -> ShowS
Show)
sfsign :: SigFigSign -> String
sfsign :: SigFigSign -> String
sfsign SigFigSign
s = String -> String -> Bool -> String
forall a. a -> a -> Bool -> a
bool String
"" String
"-" (SigFigSign
s SigFigSign -> SigFigSign -> Bool
forall a. Eq a => a -> a -> Bool
== SigFigSign
SigFigNeg)
toSigFig :: Maybe Int -> Double -> SigFig
toSigFig :: Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n Double
x = SigFigSign -> Integer -> Int -> SigFig
SigFig SigFigSign
s Integer
fs' Int
expo'
where
(SigFigSign
s, ([Int]
floatfs, Int
floate)) = (SigFigSign, ([Int], Int))
-> (SigFigSign, ([Int], Int)) -> Bool -> (SigFigSign, ([Int], Int))
forall a. a -> a -> Bool -> a
bool (SigFigSign
SigFigPos, Integer -> Double -> ([Int], Int)
forall a. RealFloat a => Integer -> a -> ([Int], Int)
floatToDigits Integer
10 Double
x) (SigFigSign
SigFigNeg, Integer -> Double -> ([Int], Int)
forall a. RealFloat a => Integer -> a -> ([Int], Int)
floatToDigits Integer
10 (-Double
x)) (Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0)
floate' :: Int
floate' = Int -> Int -> Bool -> Int
forall a. a -> a -> Bool -> a
bool Int
floate (Int
floate Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Double
x Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0)
nsig :: Int
nsig = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
floatfs) Maybe Int
n
([Int]
floatfs', Int
e) =
([Int], Int) -> ([Int], Int) -> Bool -> ([Int], Int)
forall a. a -> a -> Bool -> a
bool
([Int]
floatfs, Int
floate' Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
floatfs)
([Int]
floatfs [Int] -> [Int] -> [Int]
forall a. Semigroup a => a -> a -> a
<> Int -> Int -> [Int]
forall a. Int -> a -> [a]
replicate (Int
nsig Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
floatfs) Int
0, Int
floate' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
nsig)
([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
floatfs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
nsig)
([Int]
fs0, [Int]
fs1) = Int -> [Int] -> ([Int], [Int])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
nsig [Int]
floatfs'
fs :: Integer
fs =
Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round (Double -> Integer) -> Double -> Integer
forall a b. (a -> b) -> a -> b
$
(Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> Int) -> Int -> [Int] -> Int
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Int
x' Int
a -> Int
x' Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
a) Int
0 [Int]
fs0 :: Double)
Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Int -> Int -> Int) -> Int -> [Int] -> Int
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Int
x' Int
a -> Int
x' Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
a) Int
0 [Int]
fs1) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
10.0 Double -> Int -> Double
forall a b. (Num a, Integral b) => a -> b -> a
^ ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
fs1 :: Int))
(Integer
fs', Int
expo) =
(Integer, Int) -> (Integer, Int) -> Bool -> (Integer, Int)
forall a. a -> a -> Bool -> a
bool
(Integer
fs, Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
floatfs' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
nsig)
(Integer
fs Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
10, Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
floatfs' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
nsig Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
(String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Integer -> String
forall a. Show a => a -> String
show Integer
fs) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
nsig)
expo' :: Int
expo' = Int -> Int -> Bool -> Int
forall a. a -> a -> Bool -> a
bool Int
expo Int
0 (Integer
fs' Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 Bool -> Bool -> Bool
&& Int
expo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0)
fromSigFig :: SigFig -> Double
fromSigFig :: SigFig -> Double
fromSigFig (SigFig SigFigSign
s Integer
fs Int
e) = Double -> Double -> Bool -> Double
forall a. a -> a -> Bool -> a
bool Double
1 (-Double
1) (SigFigSign
s SigFigSign -> SigFigSign -> Bool
forall a. Eq a => a -> a -> Bool
== SigFigSign
SigFigNeg) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
fs Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
10 Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
e
incSigFig :: Int -> SigFig -> SigFig
incSigFig :: Int -> SigFig -> SigFig
incSigFig Int
n (SigFig SigFigSign
s Integer
fs Int
e) = SigFigSign -> Integer -> Int -> SigFig
SigFig SigFigSign
s (Integer
fs Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
n)) (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
eSF :: SigFig -> Int
eSF :: SigFig -> Int
eSF (SigFig SigFigSign
_ Integer
fs Int
e) = Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Integer -> String
forall a. Show a => a -> String
show Integer
fs) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
fixedSF :: Maybe Int -> SigFig -> Text
fixedSF :: Maybe Int -> SigFig -> Text
fixedSF Maybe Int
n SigFig
sf = Maybe Int -> Double -> Text
fixed Maybe Int
n (SigFig -> Double
fromSigFig SigFig
sf)
exptSF :: SigFig -> Text
exptSF :: SigFig -> Text
exptSF (SigFig SigFigSign
s Integer
i Int
e) = String -> Text
pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ SigFigSign -> String
sfsign SigFigSign
s String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
i'' String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"e" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
e'
where
i'' :: String
i''
| String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
i' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = String
i'
| Bool
otherwise = Int -> ShowS
forall a. Int -> [a] -> [a]
take Int
1 String
i' String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"." String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 String
i'
i' :: String
i' = Integer -> String
forall a. Show a => a -> String
show Integer
i
e' :: Int
e' = Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
i' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
exptSFWith :: Maybe Int -> SigFig -> Text
exptSFWith :: Maybe Int -> SigFig -> Text
exptSFWith Maybe Int
eover (SigFig SigFigSign
s Integer
i Int
e) = String -> Text
pack (SigFigSign -> String
sfsign SigFigSign
s) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Integer -> Int -> Text
posDecimalSF Integer
i (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
e') Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"e" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (Int -> String
forall a. Show a => a -> String
show Int
e')
where
e' :: Int
e' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Integer -> String
forall a. Show a => a -> String
show Integer
i) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Maybe Int
eover
posDecimalSF :: Integer -> Int -> Text
posDecimalSF :: Integer -> Int -> Text
posDecimalSF Integer
xs Int
e = String -> Text
pack String
t
where
xs' :: String
xs' = Integer -> String
forall a. Show a => a -> String
show Integer
xs
nsf :: Int
nsf = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
xs'
extrasf :: Int
extrasf = Int -> Int -> Bool -> Int
forall a. a -> a -> Bool -> a
bool (-(Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
nsf)) (-(Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
nsf)) (Integer
xs Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0)
oversf :: Int
oversf = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
xs' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
e
t :: String
t
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 = String -> String -> Bool -> String
forall a. a -> a -> Bool -> a
bool (String
xs' String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
e Char
'0') String
xs' (Integer
xs Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0)
| Int
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= -Int
nsf = String
"0." String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
extrasf Char
'0' String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
xs'
| Bool
otherwise = Int -> ShowS
forall a. Int -> [a] -> [a]
take Int
oversf String
xs' String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"." String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
oversf String
xs'
maybeCommaSF :: Bool -> SigFig -> Text
maybeCommaSF :: Bool -> SigFig -> Text
maybeCommaSF Bool
doCommas (SigFig SigFigSign
s Integer
xs Int
e) = String -> Text
pack (SigFigSign -> String
sfsign SigFigSign
s) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Text -> Text) -> (Text -> Text) -> Bool -> Text -> Text
forall a. a -> a -> Bool -> a
bool Text -> Text
forall a. a -> a
id Text -> Text
addcommas Bool
doCommas (Integer -> Int -> Text
posDecimalSF Integer
xs Int
e)
where
addcommas :: Text -> Text
addcommas =
(Text -> Text -> Text) -> (Text, Text) -> Text
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
(<>)
((Text, Text) -> Text) -> (Text -> (Text, Text)) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> (Text, Text) -> (Text, Text)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Text -> Text
Text.reverse (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
Text.intercalate Text
"," ([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Text -> [Text]
Text.chunksOf Int
3 (Text -> [Text]) -> (Text -> Text) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
Text.reverse)
((Text, Text) -> (Text, Text))
-> (Text -> (Text, Text)) -> Text -> (Text, Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> (Text, Text)
Text.breakOn Text
"."
commaSF :: SigFig -> Text
commaSF :: SigFig -> Text
commaSF = Bool -> SigFig -> Text
maybeCommaSF Bool
True
decimalSF :: SigFig -> Text
decimalSF :: SigFig -> Text
decimalSF = Bool -> SigFig -> Text
maybeCommaSF Bool
False
percentSF :: (SigFig -> Text) -> SigFig -> Text
percentSF :: (SigFig -> Text) -> SigFig -> Text
percentSF SigFig -> Text
f (SigFig SigFigSign
s Integer
figs Int
e) = (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"%") (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ SigFig -> Text
f (SigFigSign -> Integer -> Int -> SigFig
SigFig SigFigSign
s Integer
figs (Int
e Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2))
dollarSF :: (SigFig -> Text) -> SigFig -> Text
dollarSF :: (SigFig -> Text) -> SigFig -> Text
dollarSF SigFig -> Text
f SigFig
sf =
case SigFig -> SigFigSign
sfSign SigFig
sf of
SigFigSign
SigFigNeg -> Text
"-" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (SigFig -> Text) -> SigFig -> Text
dollarSF SigFig -> Text
f (SigFigSign -> Integer -> Int -> SigFig
SigFig SigFigSign
SigFigPos (SigFig -> Integer
sfFigures SigFig
sf) (SigFig -> Int
sfExponent SigFig
sf))
SigFigSign
SigFigPos -> Text
"$" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> SigFig -> Text
f SigFig
sf
fixed :: Maybe Int -> Double -> Text
fixed :: Maybe Int -> Double -> Text
fixed Maybe Int
n Double
x = String -> Text
pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Maybe Int -> Double -> ShowS
forall a. RealFloat a => Maybe Int -> a -> ShowS
showFFloat Maybe Int
n Double
x String
""
expt :: Maybe Int -> Double -> Text
expt :: Maybe Int -> Double -> Text
expt Maybe Int
n Double
x = SigFig -> Text
exptSF (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n Double
x)
exptWith :: Maybe Int -> Maybe Int -> Double -> Text
exptWith :: Maybe Int -> Maybe Int -> Double -> Text
exptWith Maybe Int
n' Maybe Int
n Double
x = Maybe Int -> SigFig -> Text
exptSFWith Maybe Int
n' (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n Double
x)
decimal :: Maybe Int -> Double -> Text
decimal :: Maybe Int -> Double -> Text
decimal Maybe Int
n Double
x = SigFig -> Text
decimalSF (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n Double
x)
comma :: Maybe Int -> Double -> Text
comma :: Maybe Int -> Double -> Text
comma Maybe Int
n Double
x = SigFig -> Text
commaSF (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n Double
x)
percent :: (SigFig -> Text) -> Maybe Int -> Double -> Text
percent :: (SigFig -> Text) -> Maybe Int -> Double -> Text
percent SigFig -> Text
f Maybe Int
n Double
x = (SigFig -> Text) -> SigFig -> Text
percentSF SigFig -> Text
f (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n Double
x)
dollar :: (SigFig -> Text) -> Maybe Int -> Double -> Text
dollar :: (SigFig -> Text) -> Maybe Int -> Double -> Text
dollar SigFig -> Text
f Maybe Int
n Double
x = (SigFig -> Text) -> SigFig -> Text
dollarSF SigFig -> Text
f (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n Double
x)
data FormatStyle
=
DecimalStyle
|
ExponentStyle (Maybe Int)
|
CommaStyle
|
FixedStyle Int
|
PercentStyle
|
DollarStyle
deriving (Int -> FormatStyle -> ShowS
[FormatStyle] -> ShowS
FormatStyle -> String
(Int -> FormatStyle -> ShowS)
-> (FormatStyle -> String)
-> ([FormatStyle] -> ShowS)
-> Show FormatStyle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FormatStyle] -> ShowS
$cshowList :: [FormatStyle] -> ShowS
show :: FormatStyle -> String
$cshow :: FormatStyle -> String
showsPrec :: Int -> FormatStyle -> ShowS
$cshowsPrec :: Int -> FormatStyle -> ShowS
Show, FormatStyle -> FormatStyle -> Bool
(FormatStyle -> FormatStyle -> Bool)
-> (FormatStyle -> FormatStyle -> Bool) -> Eq FormatStyle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FormatStyle -> FormatStyle -> Bool
$c/= :: FormatStyle -> FormatStyle -> Bool
== :: FormatStyle -> FormatStyle -> Bool
$c== :: FormatStyle -> FormatStyle -> Bool
Eq, Eq FormatStyle
Eq FormatStyle
-> (FormatStyle -> FormatStyle -> Ordering)
-> (FormatStyle -> FormatStyle -> Bool)
-> (FormatStyle -> FormatStyle -> Bool)
-> (FormatStyle -> FormatStyle -> Bool)
-> (FormatStyle -> FormatStyle -> Bool)
-> (FormatStyle -> FormatStyle -> FormatStyle)
-> (FormatStyle -> FormatStyle -> FormatStyle)
-> Ord FormatStyle
FormatStyle -> FormatStyle -> Bool
FormatStyle -> FormatStyle -> Ordering
FormatStyle -> FormatStyle -> FormatStyle
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: FormatStyle -> FormatStyle -> FormatStyle
$cmin :: FormatStyle -> FormatStyle -> FormatStyle
max :: FormatStyle -> FormatStyle -> FormatStyle
$cmax :: FormatStyle -> FormatStyle -> FormatStyle
>= :: FormatStyle -> FormatStyle -> Bool
$c>= :: FormatStyle -> FormatStyle -> Bool
> :: FormatStyle -> FormatStyle -> Bool
$c> :: FormatStyle -> FormatStyle -> Bool
<= :: FormatStyle -> FormatStyle -> Bool
$c<= :: FormatStyle -> FormatStyle -> Bool
< :: FormatStyle -> FormatStyle -> Bool
$c< :: FormatStyle -> FormatStyle -> Bool
compare :: FormatStyle -> FormatStyle -> Ordering
$ccompare :: FormatStyle -> FormatStyle -> Ordering
$cp1Ord :: Eq FormatStyle
Ord)
precStyle :: Double -> FormatStyle
precStyle :: Double -> FormatStyle
precStyle Double
x
| Double
x Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0 = FormatStyle
DecimalStyle
| Double -> Double
forall a. Num a => a -> a
abs Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0.001 = Maybe Int -> FormatStyle
ExponentStyle (Int -> Maybe Int
forall a. a -> Maybe a
Just (SigFig -> Int
eSF (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
forall a. Maybe a
Nothing Double
x)))
| Double -> Double
forall a. Num a => a -> a
abs Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
1e6 = Maybe Int -> FormatStyle
ExponentStyle (Int -> Maybe Int
forall a. a -> Maybe a
Just (SigFig -> Int
eSF (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
forall a. Maybe a
Nothing Double
x)))
| Bool
otherwise = FormatStyle
DecimalStyle
commaPrecStyle :: Double -> FormatStyle
commaPrecStyle :: Double -> FormatStyle
commaPrecStyle Double
x
| Double
x Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
0 = FormatStyle
CommaStyle
| Double -> Double
forall a. Num a => a -> a
abs Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0.001 = Maybe Int -> FormatStyle
ExponentStyle (Int -> Maybe Int
forall a. a -> Maybe a
Just (SigFig -> Int
eSF (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
forall a. Maybe a
Nothing Double
x)))
| Double -> Double
forall a. Num a => a -> a
abs Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
1e6 = Maybe Int -> FormatStyle
ExponentStyle (Int -> Maybe Int
forall a. a -> Maybe a
Just (SigFig -> Int
eSF (Maybe Int -> Double -> SigFig
toSigFig Maybe Int
forall a. Maybe a
Nothing Double
x)))
| Bool
otherwise = FormatStyle
CommaStyle
data FStyle
= FSDecimal
| FSExponent (Maybe Int)
| FSComma
| FSFixed Int
| FSPercent
| FSDollar
| FSPrec
| FSCommaPrec
| FSNone
deriving (Int -> FStyle -> ShowS
[FStyle] -> ShowS
FStyle -> String
(Int -> FStyle -> ShowS)
-> (FStyle -> String) -> ([FStyle] -> ShowS) -> Show FStyle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FStyle] -> ShowS
$cshowList :: [FStyle] -> ShowS
show :: FStyle -> String
$cshow :: FStyle -> String
showsPrec :: Int -> FStyle -> ShowS
$cshowsPrec :: Int -> FStyle -> ShowS
Show, FStyle -> FStyle -> Bool
(FStyle -> FStyle -> Bool)
-> (FStyle -> FStyle -> Bool) -> Eq FStyle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FStyle -> FStyle -> Bool
$c/= :: FStyle -> FStyle -> Bool
== :: FStyle -> FStyle -> Bool
$c== :: FStyle -> FStyle -> Bool
Eq, Eq FStyle
Eq FStyle
-> (FStyle -> FStyle -> Ordering)
-> (FStyle -> FStyle -> Bool)
-> (FStyle -> FStyle -> Bool)
-> (FStyle -> FStyle -> Bool)
-> (FStyle -> FStyle -> Bool)
-> (FStyle -> FStyle -> FStyle)
-> (FStyle -> FStyle -> FStyle)
-> Ord FStyle
FStyle -> FStyle -> Bool
FStyle -> FStyle -> Ordering
FStyle -> FStyle -> FStyle
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: FStyle -> FStyle -> FStyle
$cmin :: FStyle -> FStyle -> FStyle
max :: FStyle -> FStyle -> FStyle
$cmax :: FStyle -> FStyle -> FStyle
>= :: FStyle -> FStyle -> Bool
$c>= :: FStyle -> FStyle -> Bool
> :: FStyle -> FStyle -> Bool
$c> :: FStyle -> FStyle -> Bool
<= :: FStyle -> FStyle -> Bool
$c<= :: FStyle -> FStyle -> Bool
< :: FStyle -> FStyle -> Bool
$c< :: FStyle -> FStyle -> Bool
compare :: FStyle -> FStyle -> Ordering
$ccompare :: FStyle -> FStyle -> Ordering
$cp1Ord :: Eq FStyle
Ord)
majorityStyle :: (Double -> FormatStyle) -> [Double] -> FormatStyle
majorityStyle :: (Double -> FormatStyle) -> [Double] -> FormatStyle
majorityStyle Double -> FormatStyle
s [Double]
xs = FormatStyle
maj'
where
maj :: FormatStyle
maj = FormatStyle -> Maybe FormatStyle -> FormatStyle
forall a. a -> Maybe a -> a
fromMaybe FormatStyle
CommaStyle ([FormatStyle] -> Maybe FormatStyle
forall a. Ord a => [a] -> Maybe a
major (FormatStyle -> FormatStyle
neutralExpStyle (FormatStyle -> FormatStyle)
-> (Double -> FormatStyle) -> Double -> FormatStyle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> FormatStyle
s (Double -> FormatStyle) -> [Double] -> [FormatStyle]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Double]
xs))
maj' :: FormatStyle
maj' = FormatStyle -> FormatStyle -> Bool -> FormatStyle
forall a. a -> a -> Bool -> a
bool FormatStyle
maj (Maybe Int -> FormatStyle
ExponentStyle (Maybe Int -> Maybe (Maybe Int) -> Maybe Int
forall a. a -> Maybe a -> a
fromMaybe Maybe Int
forall a. Maybe a
Nothing Maybe (Maybe Int)
expXs)) (FormatStyle
maj FormatStyle -> FormatStyle -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe Int -> FormatStyle
ExponentStyle Maybe Int
forall a. Maybe a
Nothing)
neutralExpStyle :: FormatStyle -> FormatStyle
neutralExpStyle (ExponentStyle Maybe Int
_) = Maybe Int -> FormatStyle
ExponentStyle Maybe Int
forall a. Maybe a
Nothing
neutralExpStyle FormatStyle
x = FormatStyle
x
expXs :: Maybe (Maybe Int)
expXs = [Maybe Int] -> Maybe (Maybe Int)
forall a. Ord a => [a] -> Maybe a
major [Maybe Int
x | (ExponentStyle Maybe Int
x) <- Double -> FormatStyle
s (Double -> FormatStyle) -> [Double] -> [FormatStyle]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Double]
xs]
major :: Ord a => [a] -> Maybe a
major :: [a] -> Maybe a
major [a]
xs = (a, Integer) -> a
forall a b. (a, b) -> a
fst ((a, Integer) -> a) -> Maybe (a, Integer) -> Maybe a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(a, Integer)] -> Maybe (a, Integer)
forall a. [a] -> Maybe a
listToMaybe (((a, Integer) -> Down Integer) -> [(a, Integer)] -> [(a, Integer)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
List.sortOn (Integer -> Down Integer
forall a. a -> Down a
Down (Integer -> Down Integer)
-> ((a, Integer) -> Integer) -> (a, Integer) -> Down Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, Integer) -> Integer
forall a b. (a, b) -> b
snd) ([(a, Integer)] -> [(a, Integer)])
-> [(a, Integer)] -> [(a, Integer)]
forall a b. (a -> b) -> a -> b
$ Map a Integer -> [(a, Integer)]
forall k a. Map k a -> [(k, a)]
Map.toList (Map a Integer -> [(a, Integer)])
-> Map a Integer -> [(a, Integer)]
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer -> Integer) -> [(a, Integer)] -> Map a Integer
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+) ((,Integer
1 :: Integer) (a -> (a, Integer)) -> [a] -> [(a, Integer)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
xs))
format :: FormatStyle -> Maybe Int -> Double -> Text
format :: FormatStyle -> Maybe Int -> Double -> Text
format FormatStyle
fs Maybe Int
n Double
x = Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool (Double -> Text
go Double
x) (Text
"-" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Double -> Text
go (-Double
x)) (Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0)
where
go :: Double -> Text
go Double
x' = case FormatStyle
fs of
FormatStyle
DecimalStyle -> Maybe Int -> Double -> Text
decimal Maybe Int
n Double
x'
ExponentStyle Maybe Int
n' -> Maybe Int -> Maybe Int -> Double -> Text
exptWith Maybe Int
n' Maybe Int
n Double
x'
FormatStyle
CommaStyle -> Maybe Int -> Double -> Text
comma Maybe Int
n Double
x'
FixedStyle Int
n' -> Maybe Int -> Double -> Text
fixed (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n') Double
x'
FormatStyle
PercentStyle -> (SigFig -> Text) -> Maybe Int -> Double -> Text
percent SigFig -> Text
commaSF Maybe Int
n Double
x'
FormatStyle
DollarStyle -> (SigFig -> Text) -> Maybe Int -> Double -> Text
dollar SigFig -> Text
commaSF Maybe Int
n Double
x'
formatSF :: FormatStyle -> SigFig -> Text
formatSF :: FormatStyle -> SigFig -> Text
formatSF FormatStyle
fs SigFig
x = case FormatStyle
fs of
FormatStyle
DecimalStyle -> SigFig -> Text
decimalSF SigFig
x
ExponentStyle Maybe Int
n' -> Maybe Int -> SigFig -> Text
exptSFWith Maybe Int
n' SigFig
x
FormatStyle
CommaStyle -> SigFig -> Text
commaSF SigFig
x
FixedStyle Int
n -> Maybe Int -> Double -> Text
fixed (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n) (SigFig -> Double
fromSigFig SigFig
x)
FormatStyle
PercentStyle -> (SigFig -> Text) -> SigFig -> Text
percentSF SigFig -> Text
commaSF SigFig
x
FormatStyle
DollarStyle -> (SigFig -> Text) -> SigFig -> Text
dollarSF SigFig -> Text
commaSF SigFig
x
prec :: Maybe Int -> Double -> Text
prec :: Maybe Int -> Double -> Text
prec Maybe Int
n Double
x = FormatStyle -> Maybe Int -> Double -> Text
format (Double -> FormatStyle
precStyle Double
x) Maybe Int
n Double
x
commaPrec :: Maybe Int -> Double -> Text
commaPrec :: Maybe Int -> Double -> Text
commaPrec Maybe Int
n Double
x = FormatStyle -> Maybe Int -> Double -> Text
format (Double -> FormatStyle
commaPrecStyle Double
x) Maybe Int
n Double
x
formats ::
Bool ->
(Double -> FormatStyle) ->
Maybe Int ->
[Double] ->
[Text]
formats :: Bool -> (Double -> FormatStyle) -> Maybe Int -> [Double] -> [Text]
formats Bool
lpad Double -> FormatStyle
s Maybe Int
n0 [Double]
xs = [Text] -> [Text] -> Bool -> [Text]
forall a. a -> a -> Bool -> a
bool [Text]
fsigs ([Text] -> [Text]
lpads [Text]
fsigs) Bool
lpad
where
sigs :: [SigFig]
sigs = Maybe Int -> Double -> SigFig
toSigFig Maybe Int
n0 (Double -> SigFig) -> [Double] -> [SigFig]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Double]
xs
minexp :: Int
minexp = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum (SigFig -> Int
sfExponent (SigFig -> Int) -> [SigFig] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (SigFig -> Bool) -> [SigFig] -> [SigFig]
forall a. (a -> Bool) -> [a] -> [a]
filter (\SigFig
x -> SigFig -> Integer
sfFigures SigFig
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0) [SigFig]
sigs)
sigs' :: [SigFig]
sigs' = (\SigFig
x -> SigFig -> SigFig -> Bool -> SigFig
forall a. a -> a -> Bool -> a
bool (Int -> SigFig -> SigFig
incSigFig (SigFig -> Int
sfExponent SigFig
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
minexp) SigFig
x) (SigFig
x {sfExponent :: Int
sfExponent = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
1 Int
minexp}) (SigFig -> Integer
sfFigures SigFig
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0)) (SigFig -> SigFig) -> [SigFig] -> [SigFig]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SigFig]
sigs
maj :: FormatStyle
maj = (Double -> FormatStyle) -> [Double] -> FormatStyle
majorityStyle Double -> FormatStyle
s (SigFig -> Double
fromSigFig (SigFig -> Double) -> [SigFig] -> [Double]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SigFig]
sigs')
fsigs :: [Text]
fsigs = FormatStyle -> SigFig -> Text
formatSF FormatStyle
maj (SigFig -> Text) -> [SigFig] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SigFig]
sigs'
lpads :: [Text] -> [Text]
lpads :: [Text] -> [Text]
lpads [Text]
ts = (\Text
x -> [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat (Int -> Text -> [Text]
forall a. Int -> a -> [a]
replicate (Int
maxl Int -> Int -> Int
forall a. Num a => a -> a -> a
- Text -> Int
Text.length Text
x) Text
" ") Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
x) (Text -> Text) -> [Text] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text]
ts
where
maxl :: Int
maxl = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ Text -> Int
Text.length (Text -> Int) -> [Text] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text]
ts
distinguish ::
Int ->
Bool ->
(Double -> FormatStyle) ->
Maybe Int ->
[Double] ->
[Text]
distinguish :: Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad Double -> FormatStyle
f Maybe Int
n [Double]
xs =
case Maybe Int
n of
Maybe Int
Nothing -> Bool -> (Double -> FormatStyle) -> Maybe Int -> [Double] -> [Text]
formats Bool
pad Double -> FormatStyle
f Maybe Int
forall a. Maybe a
Nothing [Double]
xs
Just Int
n0 -> Int -> [Double] -> [Text]
loop Int
n0 [Double]
xs
where
loop :: Int -> [Double] -> [Text]
loop Int
n' [Double]
xs' =
let s :: [Text]
s = Bool -> (Double -> FormatStyle) -> Maybe Int -> [Double] -> [Text]
formats Bool
pad Double -> FormatStyle
f (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
n') [Double]
xs'
in [Text] -> [Text] -> Bool -> [Text]
forall a. a -> a -> Bool -> a
bool (Int -> [Double] -> [Text]
loop (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n') [Double]
xs') [Text]
s ([Text]
s [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== [Text] -> [Text]
forall a. Ord a => [a] -> [a]
nubOrd [Text]
s Bool -> Bool -> Bool
|| Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
maxi)
data FormatN = FormatN {FormatN -> FStyle
fstyle :: FStyle, FormatN -> Maybe Int
sigFigs :: Maybe Int, FormatN -> Bool
addLPad :: Bool} deriving (FormatN -> FormatN -> Bool
(FormatN -> FormatN -> Bool)
-> (FormatN -> FormatN -> Bool) -> Eq FormatN
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FormatN -> FormatN -> Bool
$c/= :: FormatN -> FormatN -> Bool
== :: FormatN -> FormatN -> Bool
$c== :: FormatN -> FormatN -> Bool
Eq, Int -> FormatN -> ShowS
[FormatN] -> ShowS
FormatN -> String
(Int -> FormatN -> ShowS)
-> (FormatN -> String) -> ([FormatN] -> ShowS) -> Show FormatN
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FormatN] -> ShowS
$cshowList :: [FormatN] -> ShowS
show :: FormatN -> String
$cshow :: FormatN -> String
showsPrec :: Int -> FormatN -> ShowS
$cshowsPrec :: Int -> FormatN -> ShowS
Show, (forall x. FormatN -> Rep FormatN x)
-> (forall x. Rep FormatN x -> FormatN) -> Generic FormatN
forall x. Rep FormatN x -> FormatN
forall x. FormatN -> Rep FormatN x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep FormatN x -> FormatN
$cfrom :: forall x. FormatN -> Rep FormatN x
Generic)
defaultFormatN :: FormatN
defaultFormatN :: FormatN
defaultFormatN = FStyle -> Maybe Int -> Bool -> FormatN
FormatN FStyle
FSCommaPrec (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2) Bool
True
formatN :: FormatN -> Double -> Text
formatN :: FormatN -> Double -> Text
formatN (FormatN FStyle
FSDecimal Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format FormatStyle
DecimalStyle Maybe Int
sf Double
x
formatN (FormatN (FSExponent Maybe Int
n) Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format (Maybe Int -> FormatStyle
ExponentStyle Maybe Int
n) Maybe Int
sf Double
x
formatN (FormatN FStyle
FSComma Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format FormatStyle
CommaStyle Maybe Int
sf Double
x
formatN (FormatN (FSFixed Int
n) Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format (Int -> FormatStyle
FixedStyle Int
n) Maybe Int
sf Double
x
formatN (FormatN FStyle
FSPercent Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format FormatStyle
PercentStyle Maybe Int
sf Double
x
formatN (FormatN FStyle
FSDollar Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format FormatStyle
DollarStyle Maybe Int
sf Double
x
formatN (FormatN FStyle
FSPrec Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format (Double -> FormatStyle
precStyle Double
x) Maybe Int
sf Double
x
formatN (FormatN FStyle
FSCommaPrec Maybe Int
sf Bool
_) Double
x = FormatStyle -> Maybe Int -> Double -> Text
format (Double -> FormatStyle
commaPrecStyle Double
x) Maybe Int
sf Double
x
formatN (FormatN FStyle
FSNone Maybe Int
_ Bool
_) Double
x = String -> Text
pack (Double -> String
forall a. Show a => a -> String
show Double
x)
formatNs :: Int -> FormatN -> [Double] -> [Text]
formatNs :: Int -> FormatN -> [Double] -> [Text]
formatNs Int
maxi (FormatN FStyle
FSDecimal Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad (FormatStyle -> Double -> FormatStyle
forall a b. a -> b -> a
const FormatStyle
DecimalStyle) Maybe Int
sf [Double]
x
formatNs Int
maxi (FormatN (FSExponent Maybe Int
n) Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad (FormatStyle -> Double -> FormatStyle
forall a b. a -> b -> a
const (Maybe Int -> FormatStyle
ExponentStyle Maybe Int
n)) Maybe Int
sf [Double]
x
formatNs Int
maxi (FormatN FStyle
FSComma Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad (FormatStyle -> Double -> FormatStyle
forall a b. a -> b -> a
const FormatStyle
CommaStyle) Maybe Int
sf [Double]
x
formatNs Int
maxi (FormatN (FSFixed Int
n) Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad (FormatStyle -> Double -> FormatStyle
forall a b. a -> b -> a
const (Int -> FormatStyle
FixedStyle Int
n)) Maybe Int
sf [Double]
x
formatNs Int
maxi (FormatN FStyle
FSPercent Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad (FormatStyle -> Double -> FormatStyle
forall a b. a -> b -> a
const FormatStyle
PercentStyle) Maybe Int
sf [Double]
x
formatNs Int
maxi (FormatN FStyle
FSDollar Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad (FormatStyle -> Double -> FormatStyle
forall a b. a -> b -> a
const FormatStyle
DollarStyle) Maybe Int
sf [Double]
x
formatNs Int
maxi (FormatN FStyle
FSPrec Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad Double -> FormatStyle
precStyle Maybe Int
sf [Double]
x
formatNs Int
maxi (FormatN FStyle
FSCommaPrec Maybe Int
sf Bool
pad) [Double]
x = Int
-> Bool
-> (Double -> FormatStyle)
-> Maybe Int
-> [Double]
-> [Text]
distinguish Int
maxi Bool
pad Double -> FormatStyle
commaPrecStyle Maybe Int
sf [Double]
x
formatNs Int
_ (FormatN FStyle
FSNone Maybe Int
_ Bool
pad) [Double]
x = ([Text] -> [Text])
-> ([Text] -> [Text]) -> Bool -> [Text] -> [Text]
forall a. a -> a -> Bool -> a
bool [Text] -> [Text]
forall a. a -> a
id [Text] -> [Text]
lpads Bool
pad ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ String -> Text
pack (String -> Text) -> (Double -> String) -> Double -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> String
forall a. Show a => a -> String
show (Double -> Text) -> [Double] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Double]
x
formatOrShow :: FormatStyle -> Maybe Int -> Double -> Text
formatOrShow :: FormatStyle -> Maybe Int -> Double -> Text
formatOrShow FormatStyle
f Maybe Int
n Double
x = Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool (Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool Text
f' (String -> Text
pack String
s') (Text -> Int
Text.length (String -> Text
pack String
s') Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Text -> Int
Text.length Text
f')) Text
"0" (Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
1e-6 Bool -> Bool -> Bool
&& Double
x Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> -Double
1e-6)
where
f' :: Text
f' = FormatStyle -> Maybe Int -> Double -> Text
format FormatStyle
f Maybe Int
n Double
x
s' :: String
s' = Double -> String
forall a. Show a => a -> String
show Double
x