{- numbers for humans
 -
 - Copyright 2012-2021 Joey Hess <id@joeyh.name>
 -
 - License: BSD-2-clause
 -}

module Utility.HumanNumber (showImprecise) where

{- Displays a fractional value as a string with a limited number
 - of decimal digits. -}
showImprecise :: RealFrac a => Int -> a -> String
showImprecise :: forall a. RealFrac a => Int -> a -> String
showImprecise Int
precision a
n
	| Int
precision forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
|| Integer
remainder' forall a. Eq a => a -> a -> Bool
== Integer
0 = forall a. Show a => a -> String
show (forall a b. (RealFrac a, Integral b) => a -> b
round a
n :: Integer)
	| Bool
otherwise = forall a. Show a => a -> String
show Integer
int' forall a. [a] -> [a] -> [a]
++ String
"." forall a. [a] -> [a] -> [a]
++ String -> String
striptrailing0s (String -> String
pad0s forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Integer
remainder')
  where
	int :: Integer
	(Integer
int, a
frac) = forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction a
n
	remainder :: Integer
remainder = forall a b. (RealFrac a, Integral b) => a -> b
round (a
frac forall a. Num a => a -> a -> a
* a
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Int
precision) :: Integer
	(Integer
int', Integer
remainder')
		-- carry the 1
		| Integer
remainder forall a. Eq a => a -> a -> Bool
== Integer
10 forall a b. (Num a, Integral b) => a -> b -> a
^ Int
precision = (Integer
int forall a. Num a => a -> a -> a
+ Integer
1, Integer
0)
		| Bool
otherwise = (Integer
int, Integer
remainder)
	pad0s :: String -> String
pad0s String
s = forall a. Int -> a -> [a]
replicate (Int
precision forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s) Char
'0' forall a. [a] -> [a] -> [a]
++ String
s
	striptrailing0s :: String -> String
striptrailing0s = forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
dropWhile (forall a. Eq a => a -> a -> Bool
== Char
'0') forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse