    {- 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 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0 Bool -> Bool -> Bool
    || Integer
    remainder' Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    0 = Integer -> String
    forall a. Show a => a -> String
    show (a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round a
    n :: Integer)
    	| Bool
    otherwise = Integer -> String
    forall a. Show a => a -> String
    show Integer
    int' String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> String
    striptrailing0s (String -> String
    pad0s (String -> String) -> String -> String
    forall a b. (a -> b) -> a -> b
    $ Integer -> String
    forall a. Show a => a -> String
    show Integer
    remainder')
      where
    	int :: Integer
    	(Integer
    int, a
    frac) = a -> (Integer, a)
    forall b. Integral b => a -> (b, a)
    forall a b. (RealFrac a, Integral b) => a -> (b, a)
    properFraction a
    n
    	remainder :: Integer
    remainder = a -> Integer
    forall b. Integral b => a -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (a
    frac a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    10 a -> Int -> a
    forall a b. (Num a, Integral b) => a -> b -> a
    ^ Int
    precision) :: Integer
    	(Integer
    int', Integer
    remainder')
    		-- carry the 1
    		| Integer
    remainder Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    10 Integer -> Int -> Integer
    forall a b. (Num a, Integral b) => a -> b -> a
    ^ Int
    precision = (Integer
    int Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Integer
    1, Integer
    0)
    		| Bool
    otherwise = (Integer
    int, Integer
    remainder)
    	pad0s :: String -> String
    pad0s String
    s = Int -> Char -> String
    forall a. Int -> a -> [a]
    replicate (Int
    precision Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - String -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length String
    s) Char
    '0' String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    s
    	striptrailing0s :: String -> String
    striptrailing0s = String -> String
    forall a. [a] -> [a]
    reverse (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '0') (String -> String) -> (String -> String) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> String
    forall a. [a] -> [a]
    reverse