    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE OverloadedStrings #-}
    -- |
    -- Module      : Formatting.Formatters
    -- Copyright   : (c) 2013 Chris Done, 2013 Shachaf Ben-Kiki
    -- License     : BSD3
    -- Maintainer  : alex@farfromthere.net
    -- Stability   : experimental
    -- Portability : GHC
    --
    -- Formatting functions.

    module Formatting.Formatters
      (
      -- * Text/string types
      text,
      stext,
      string,
      shown,
      char,
      builder,
      fconst,
      -- * Numbers
      int,
      float,
      fixed,
      sci,
      scifmt,
      shortest,
      groupInt,
      commas,
      ords,
      plural,
      asInt,
      -- * Padding
      left,
      right,
      center,
      fitLeft,
      fitRight,
      -- * Bases
      base,
      bin,
      oct,
      hex,
      prefixBin,
      prefixOct,
      prefixHex,
      bytes,
      -- * Buildables
      build,
      Buildable,
      ) where

    import           Formatting.Internal

    import           Data.Char (chr, ord)
    import           Data.Scientific
    import qualified Data.Text as S
    import qualified Data.Text as T
    import           Formatting.Buildable (Buildable)
    import qualified Formatting.Buildable as B (build)
    import qualified Data.Text.Format as T
    import           Data.Text.Lazy (Text)
    import qualified Data.Text.Lazy as LT
    import           Data.Text.Lazy.Builder (Builder)
    import qualified Data.Text.Lazy.Builder as T
    import           Data.Text.Lazy.Builder.Scientific
    import           Numeric (showIntAtBase)

    -- $setup
    -- >>> import Formatting.Internal

    -- | Output a lazy text.
    text :: Format r (Text -> r)
    text :: forall r. Format r (Text -> r)
    text = (Text -> Builder) -> Format r (Text -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later Text -> Builder
    T.fromLazyText
    {-# INLINE text #-}

    -- | Output a strict text.
    stext :: Format r (S.Text -> r)
    stext :: forall r. Format r (Text -> r)
    stext = (Text -> Builder) -> Format r (Text -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later Text -> Builder
    T.fromText
    {-# INLINE stext #-}

    -- | Output a string.
    string :: Format r (String -> r)
    string :: forall r. Format r ([Char] -> r)
    string = ([Char] -> Builder) -> Format r ([Char] -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Text -> Builder
    T.fromText (Text -> Builder) -> ([Char] -> Text) -> [Char] -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    T.pack)
    {-# INLINE string #-}

    -- | Output a showable value (instance of 'Show') by turning it into
    -- 'Text':
    --
    -- >>> format ("Value number " % shown % " is " % shown % ".") 42 False
    -- "Value number 42 is False."
    shown :: Show a => Format r (a -> r)
    shown :: forall a r. Show a => Format r (a -> r)
    shown = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Text -> Builder
    T.fromText (Text -> Builder) -> (a -> Text) -> a -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    T.pack ([Char] -> Text) -> (a -> [Char]) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> [Char]
    forall a. Show a => a -> [Char]
    show)
    {-# INLINE shown #-}

    -- | Output a character.
    char :: Format r (Char -> r)
    char :: forall r. Format r (Char -> r)
    char = (Char -> Builder) -> Format r (Char -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later Char -> Builder
    forall p. Buildable p => p -> Builder
    B.build
    {-# INLINE char #-}

    -- | Build a builder.
    builder :: Format r (Builder -> r)
    builder :: forall r. Format r (Builder -> r)
    builder = (Builder -> Builder) -> Format r (Builder -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later Builder -> Builder
    forall a. a -> a
    id
    {-# INLINE builder #-}

    -- | Like `const` but for formatters.
    fconst :: Builder -> Format r (a -> r)
    fconst :: forall r a. Builder -> Format r (a -> r)
    fconst Builder
    m = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Builder -> a -> Builder
    forall a b. a -> b -> a
    const Builder
    m)
    {-# INLINE fconst #-}

    -- | Build anything that implements the "Buildable" class.
    build :: Buildable a => Format r (a -> r)
    build :: forall a r. Buildable a => Format r (a -> r)
    build = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later a -> Builder
    forall p. Buildable p => p -> Builder
    B.build
    {-# INLINE build #-}

    -- | Render an integral e.g. 123 -> \"123\", 0 -> \"0\".
    int :: Integral a => Format r (a -> r)
    int :: forall a r. Integral a => Format r (a -> r)
    int = Int -> Format r (a -> r)
    forall a r. Integral a => Int -> Format r (a -> r)
    base Int
    10
    {-# INLINE int #-}

    -- | Render some floating point with the usual notation, e.g. 123.32 => \"123.32\"
    float :: Real a => Format r (a -> r)
    float :: forall a r. Real a => Format r (a -> r)
    float = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later a -> Builder
    forall a. Real a => a -> Builder
    T.shortest
    {-# INLINE float #-}

    -- | Render a floating point number using normal notation, with the
    -- given number of decimal places.
    fixed :: Real a => Int -> Format r (a -> r)
    fixed :: forall a r. Real a => Int -> Format r (a -> r)
    fixed Int
    i = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Int -> a -> Builder
    forall a. Real a => Int -> a -> Builder
    T.fixed Int
    i)
    {-# INLINE fixed #-}

    -- | Render a floating point number using the smallest number of
    -- digits that correctly represent it. Note that in the case of whole
    -- numbers it will still add one decimal place, e.g. "1.0".
    shortest :: Real a => Format r (a -> r)
    shortest :: forall a r. Real a => Format r (a -> r)
    shortest = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later a -> Builder
    forall a. Real a => a -> Builder
    T.shortest
    {-# INLINE shortest #-}

    -- | Render a scientific number.
    sci :: Format r (Scientific -> r)
    sci :: forall r. Format r (Scientific -> r)
    sci = (Scientific -> Builder) -> Format r (Scientific -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later Scientific -> Builder
    scientificBuilder
    {-# INLINE sci #-}

    -- | Render a scientific number with options.
    scifmt :: FPFormat -> Maybe Int -> Format r (Scientific -> r)
    scifmt :: forall r. FPFormat -> Maybe Int -> Format r (Scientific -> r)
    scifmt FPFormat
    f Maybe Int
    i = (Scientific -> Builder) -> Format r (Scientific -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (FPFormat -> Maybe Int -> Scientific -> Builder
    formatScientificBuilder FPFormat
    f Maybe Int
    i)
    {-# INLINE scifmt #-}

    -- | Shows the Int value of Enum instances using 'fromEnum'.
    --
    -- >>> format ("Got: " % char % " (" % asInt % ")") 'a' 'a'
    -- "Got: a (97)"
    asInt :: Enum a => Format r (a -> r)
    asInt :: forall a r. Enum a => Format r (a -> r)
    asInt = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Int -> Builder
    forall a. Real a => a -> Builder
    T.shortest (Int -> Builder) -> (a -> Int) -> a -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Int
    forall a. Enum a => a -> Int
    fromEnum)
    {-# INLINE asInt #-}

    -- | Pad the left hand side of a string until it reaches k characters
    -- wide, if necessary filling with character c.
    left :: Buildable a => Int -> Char -> Format r (a -> r)
    left :: forall a r. Buildable a => Int -> Char -> Format r (a -> r)
    left Int
    i Char
    c = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Int -> Char -> a -> Builder
    forall a. Buildable a => Int -> Char -> a -> Builder
    T.left Int
    i Char
    c)
    {-# INLINE left #-}

    -- | Pad the right hand side of a string until it reaches k characters
    -- wide, if necessary filling with character c.
    right :: Buildable a => Int -> Char -> Format r (a -> r)
    right :: forall a r. Buildable a => Int -> Char -> Format r (a -> r)
    right Int
    i Char
    c = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Int -> Char -> a -> Builder
    forall a. Buildable a => Int -> Char -> a -> Builder
    T.right Int
    i Char
    c)
    {-# INLINE right #-}

    -- | Pad the left & right hand side of a string until it reaches k characters
    -- wide, if necessary filling with character c.
    center :: Buildable a => Int -> Char -> Format r (a -> r)
    center :: forall a r. Buildable a => Int -> Char -> Format r (a -> r)
    center Int
    i Char
    c = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later a -> Builder
    centerT where
      centerT :: a -> Builder
    centerT = Text -> Builder
    T.fromLazyText (Text -> Builder) -> (a -> Text) -> a -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Char -> Text -> Text
    LT.center (Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    i) Char
    c (Text -> Text) -> (a -> Text) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    T.toLazyText (Builder -> Text) -> (a -> Builder) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Builder
    forall p. Buildable p => p -> Builder
    B.build

    -- | Group integral numbers, e.g. groupInt 2 '.' on 123456 -> \"12.34.56\".
    groupInt :: (Buildable n,Integral n) => Int -> Char -> Format r (n -> r)
    groupInt :: forall n r.
    (Buildable n, Integral n) =>
    Int -> Char -> Format r (n -> r)
    groupInt Int
    0 Char
    _ = (n -> Builder) -> Format r (n -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later n -> Builder
    forall p. Buildable p => p -> Builder
    B.build
    groupInt Int
    i Char
    c =
      (n -> Builder) -> Format r (n -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later
        (\n
    n ->
           if n
    n n -> n -> Bool
    forall a. Ord a => a -> a -> Bool
    < n
    0
             then Builder
    "-" Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> n -> Builder
    commaize (n -> n
    forall a. Num a => a -> a
    negate n
    n)
             else n -> Builder
    commaize n
    n)
      where
        commaize :: n -> Builder
    commaize =
          Text -> Builder
    T.fromLazyText (Text -> Builder) -> (n -> Text) -> n -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
          Text -> Text
    LT.reverse (Text -> Text) -> (n -> Text) -> n -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
          ((Char, Char) -> Text -> Text) -> Text -> [(Char, Char)] -> Text
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (Char, Char) -> Text -> Text
    merge Text
    "" ([(Char, Char)] -> Text) -> (n -> [(Char, Char)]) -> n -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
          Text -> Text -> [(Char, Char)]
    LT.zip (Text
    zeros Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    forall {t}. Semigroup t => t -> t
    cycle' Text
    zeros') (Text -> [(Char, Char)]) -> (n -> Text) -> n -> [(Char, Char)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    LT.reverse (Text -> Text) -> (n -> Text) -> n -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    T.toLazyText (Builder -> Text) -> (n -> Builder) -> n -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . n -> Builder
    forall p. Buildable p => p -> Builder
    B.build
        zeros :: Text
    zeros = Int64 -> Text -> Text
    LT.replicate (Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    i) (Char -> Text
    LT.singleton Char
    '0')
        zeros' :: Text
    zeros' = Char -> Text
    LT.singleton Char
    c Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> HasCallStack => Text -> Text
    Text -> Text
    LT.tail Text
    zeros
        merge :: (Char, Char) -> Text -> Text
    merge (Char
    f, Char
    c') Text
    rest
          | Char
    f Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    c = Char -> Text
    LT.singleton Char
    c Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Char -> Text
    LT.singleton Char
    c' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    rest
          | Bool
    otherwise = Char -> Text
    LT.singleton Char
    c' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    rest
        cycle' :: t -> t
    cycle' t
    xs = t
    xs t -> t -> t
    forall a. Semigroup a => a -> a -> a
    <> t -> t
    cycle' t
    xs

    -- | Fit in the given length, truncating on the left.
    fitLeft :: Buildable a => Int -> Format r (a -> r)
    fitLeft :: forall a r. Buildable a => Int -> Format r (a -> r)
    fitLeft Int
    size = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Int64 -> a -> Builder
    forall {a}. Buildable a => Int64 -> a -> Builder
    fit (Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size)) where
      fit :: Int64 -> a -> Builder
    fit Int64
    i = Text -> Builder
    T.fromLazyText (Text -> Builder) -> (a -> Text) -> a -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int64 -> Text -> Text
    LT.take Int64
    i (Text -> Text) -> (a -> Text) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    T.toLazyText (Builder -> Text) -> (a -> Builder) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Builder
    forall p. Buildable p => p -> Builder
    B.build

    -- | Fit in the given length, truncating on the right.
    fitRight :: Buildable a => Int -> Format r (a -> r)
    fitRight :: forall a r. Buildable a => Int -> Format r (a -> r)
    fitRight Int
    size = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (Int64 -> a -> Builder
    forall {a}. Buildable a => Int64 -> a -> Builder
    fit (Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size)) where
      fit :: Int64 -> a -> Builder
    fit Int64
    i = Text -> Builder
    T.fromLazyText (Text -> Builder) -> (a -> Text) -> a -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
              (\Text
    t -> Int64 -> Text -> Text
    LT.drop (Text -> Int64
    LT.length Text
    t Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    - Int64
    i) Text
    t)
              (Text -> Text) -> (a -> Text) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    T.toLazyText
              (Builder -> Text) -> (a -> Builder) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Builder
    forall p. Buildable p => p -> Builder
    B.build

    -- | Add commas to an integral, e.g 12000 -> \ "12,000".
    commas :: (Buildable n,Integral n) => Format r (n -> r)
    commas :: forall n r. (Buildable n, Integral n) => Format r (n -> r)
    commas = Int -> Char -> Format r (n -> r)
    forall n r.
    (Buildable n, Integral n) =>
    Int -> Char -> Format r (n -> r)
    groupInt Int
    3 Char
    ','
    {-# INLINE commas #-}

    -- | Add a suffix to an integral, e.g. 1st, 2nd, 3rd, 21st.
    ords :: Integral n => Format r (n -> r)
    ords :: forall a r. Integral a => Format r (a -> r)
    ords = (n -> Builder) -> Format r (n -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later n -> Builder
    forall {a}. Integral a => a -> Builder
    go
      where go :: a -> Builder
    go a
    n
              | a
    tens a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    > a
    3 Bool -> Bool -> Bool
    && a
    tens a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    21 = Int -> a -> Builder
    forall a. Real a => Int -> a -> Builder
    T.fixed Int
    0 a
    n Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> Builder
    "th"
              | Bool
    otherwise =
                Int -> a -> Builder
    forall a. Real a => Int -> a -> Builder
    T.fixed Int
    0 a
    n Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <>
                case a
    n a -> a -> a
    forall a. Integral a => a -> a -> a
    `mod` a
    10 of
                  a
    1 -> Builder
    "st"
                  a
    2 -> Builder
    "nd"
                  a
    3 -> Builder
    "rd"
                  a
    _ -> Builder
    "th"
              where tens :: a
    tens = a
    n a -> a -> a
    forall a. Integral a => a -> a -> a
    `mod` a
    100

    -- | English plural suffix for an integral.
    --
    -- For example:
    --
    -- >>> :set -XOverloadedStrings
    -- >>> formatPeople = format (int % " " <> plural "person" "people" % ".") :: Int -> Data.Text.Lazy.Text
    -- >>> formatPeople 1
    -- "1 person."
    -- >>> formatPeople 3
    -- "3 people."
    plural :: (Num a, Eq a) => Text -> Text -> Format r (a -> r)
    plural :: forall a r. (Num a, Eq a) => Text -> Text -> Format r (a -> r)
    plural Text
    s Text
    p = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later (\a
    i -> if a
    i a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    1 then Text -> Builder
    forall p. Buildable p => p -> Builder
    B.build Text
    s else Text -> Builder
    forall p. Buildable p => p -> Builder
    B.build Text
    p)

    -- | Render an integral at base n.
    base :: Integral a => Int -> Format r (a -> r)
    base :: forall a r. Integral a => Int -> Format r (a -> r)
    base Int
    numBase = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later ([Char] -> Builder
    forall p. Buildable p => p -> Builder
    B.build ([Char] -> Builder) -> (a -> [Char]) -> a -> Builder
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> a -> [Char]
    forall a. Integral a => Int -> a -> [Char]
    atBase Int
    numBase)
    {-# INLINE base #-}

    -- | Render an integer using binary notation. (No leading 0b is
    -- added.) Defined as @bin = 'base' 2@.
    bin :: Integral a => Format r (a -> r)
    bin :: forall a r. Integral a => Format r (a -> r)
    bin = Int -> Format r (a -> r)
    forall a r. Integral a => Int -> Format r (a -> r)
    base Int
    2
    {-# INLINE bin #-}

    -- | Render an integer using octal notation. (No leading 0o is
    -- added.) Defined as @oct = 'base' 8@.
    oct :: Integral a => Format r (a -> r)
    oct :: forall a r. Integral a => Format r (a -> r)
    oct = Int -> Format r (a -> r)
    forall a r. Integral a => Int -> Format r (a -> r)
    base Int
    8
    {-# INLINE oct #-}

    -- | Render an integer using hexadecimal notation. (No leading 0x is
    -- added.) Has a specialized implementation.
    hex :: Integral a => Format r (a -> r)
    hex :: forall a r. Integral a => Format r (a -> r)
    hex = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later a -> Builder
    forall {a}. Integral a => a -> Builder
    T.hex
    {-# INLINE hex #-}

    -- | Render an integer using binary notation with a leading 0b.
    --
    -- See also 'Formatting.Combinators.binPrefix' for fixed-width formatting.
    prefixBin :: Integral a => Format r (a -> r)
    prefixBin :: forall a r. Integral a => Format r (a -> r)
    prefixBin = Format (a -> r) (a -> r)
    "0b" Format (a -> r) (a -> r) -> Format r (a -> r) -> Format r (a -> r)
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Format r (a -> r)
    forall a r. Integral a => Format r (a -> r)
    bin
    {-# INLINE prefixBin #-}

    -- | Render an integer using octal notation with a leading 0o.
    --
    -- See also 'Formatting.Combinators.octPrefix' for fixed-width formatting.
    prefixOct :: Integral a => Format r (a -> r)
    prefixOct :: forall a r. Integral a => Format r (a -> r)
    prefixOct = Format (a -> r) (a -> r)
    "0o" Format (a -> r) (a -> r) -> Format r (a -> r) -> Format r (a -> r)
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Format r (a -> r)
    forall a r. Integral a => Format r (a -> r)
    oct
    {-# INLINE prefixOct #-}

    -- | Render an integer using hexadecimal notation with a leading 0x.
    --
    -- See also 'Formatting.Combinators.hexPrefix' for fixed-width formatting.
    prefixHex :: Integral a => Format r (a -> r)
    prefixHex :: forall a r. Integral a => Format r (a -> r)
    prefixHex = Format (a -> r) (a -> r)
    "0x" Format (a -> r) (a -> r) -> Format r (a -> r) -> Format r (a -> r)
    forall r a r'. Format r a -> Format r' r -> Format r' a
    % Format r (a -> r)
    forall a r. Integral a => Format r (a -> r)
    hex
    {-# INLINE prefixHex #-}

    -- The following code is mostly taken from `Numeric.Lens.' (from
    -- `lens') and modified.

    -- | Internal function that converts a number to a base base-2 through
    -- base-36.
    atBase :: Integral a => Int -> a -> String
    atBase :: forall a. Integral a => Int -> a -> [Char]
    atBase Int
    b a
    _ | Int
    b Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    2 Bool -> Bool -> Bool
    || Int
    b Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    36 = [Char] -> [Char]
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "base: Invalid base " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    b)
    atBase Int
    b a
    n =
      (Integer -> [Char] -> [Char]) -> Integer -> [Char] -> [Char]
    forall a.
    Real a =>
    (a -> [Char] -> [Char]) -> a -> [Char] -> [Char]
    showSigned' (Integer -> (Int -> Char) -> Integer -> [Char] -> [Char]
    forall a. Integral a => a -> (Int -> Char) -> a -> [Char] -> [Char]
    showIntAtBase (Int -> Integer
    forall a. Integral a => a -> Integer
    toInteger Int
    b) Int -> Char
    intToDigit') (a -> Integer
    forall a. Integral a => a -> Integer
    toInteger a
    n) [Char]
    ""
    {-# INLINE atBase #-}

    -- | A simpler variant of 'Numeric.showSigned' that only prepends a dash and
    -- doesn't know about parentheses
    showSigned' :: Real a => (a -> ShowS) -> a -> ShowS
    showSigned' :: forall a.
    Real a =>
    (a -> [Char] -> [Char]) -> a -> [Char] -> [Char]
    showSigned' a -> [Char] -> [Char]
    f a
    n
      | a
    n a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    0     = Char -> [Char] -> [Char]
    showChar Char
    '-' ([Char] -> [Char]) -> ([Char] -> [Char]) -> [Char] -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> [Char] -> [Char]
    f (a -> a
    forall a. Num a => a -> a
    negate a
    n)
      | Bool
    otherwise = a -> [Char] -> [Char]
    f a
    n

    -- | Like 'Data.Char.intToDigit', but handles up to base-36
    intToDigit' :: Int -> Char
    intToDigit' :: Int -> Char
    intToDigit' Int
    i
      | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    0  Bool -> Bool -> Bool
    && Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    10 = Int -> Char
    chr (Char -> Int
    ord Char
    '0' Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    i)
      | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    10 Bool -> Bool -> Bool
    && Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    36 = Int -> Char
    chr (Char -> Int
    ord Char
    'a' Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    10)
      | Bool
    otherwise = [Char] -> Char
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "intToDigit': Invalid int " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    i)

    -- | Renders a given byte count using an appropiate decimal binary suffix:
    --
    -- >>> format (bytes shortest) 1024
    -- "1KB"
    --
    -- >>> format (bytes (fixed 2 % " ")) (1024*1024*5)
    -- "5.00 MB"
    --
    bytes :: (Ord f,Integral a,Fractional f)
          => Format Builder (f -> Builder) -- ^ formatter for the decimal part
          -> Format r (a -> r)
    bytes :: forall f a r.
    (Ord f, Integral a, Fractional f) =>
    Format Builder (f -> Builder) -> Format r (a -> r)
    bytes Format Builder (f -> Builder)
    d = (a -> Builder) -> Format r (a -> r)
    forall a r. (a -> Builder) -> Format r (a -> r)
    later a -> Builder
    forall {a}. Integral a => a -> Builder
    go
      where go :: a -> Builder
    go a
    bs =
              Format Builder (f -> Builder) -> f -> Builder
    forall a. Format Builder a -> a
    bprint Format Builder (f -> Builder)
    d (a -> f
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a -> a
    forall a. Num a => a -> a
    signum a
    bs) f -> f -> f
    forall a. Num a => a -> a -> a
    * f
    dec) Builder -> Builder -> Builder
    forall a. Semigroup a => a -> a -> a
    <> [Builder]
    bytesSuffixes [Builder] -> Int -> Builder
    forall a. HasCallStack => [a] -> Int -> a
    !!
              Int
    i
              where (f
    dec,Int
    i) = a -> (f, Int)
    forall {a} {a}. (Fractional a, Integral a, Ord a) => a -> (a, Int)
    getSuffix (a -> a
    forall a. Num a => a -> a
    abs a
    bs)
            getSuffix :: a -> (a, Int)
    getSuffix a
    n =
              ((a, Int) -> Bool)
    -> ((a, Int) -> (a, Int)) -> (a, Int) -> (a, Int)
    forall a. (a -> Bool) -> (a -> a) -> a -> a
    until (a, Int) -> Bool
    forall {a}. (Ord a, Num a) => (a, Int) -> Bool
    p
                    (\(a
    x,Int
    y) -> (a
    x a -> a -> a
    forall a. Fractional a => a -> a -> a
    / a
    1024,Int
    y Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1))
                    (a -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n,Int
    0)
              where p :: (a, Int) -> Bool
    p (a
    n',Int
    numDivs) =
                      a
    n' a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < a
    1024 Bool -> Bool -> Bool
    || Int
    numDivs Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == ([Builder] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Builder]
    bytesSuffixes Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1)
            bytesSuffixes :: [Builder]
    bytesSuffixes =
              [Builder
    "B",Builder
    "KB",Builder
    "MB",Builder
    "GB",Builder
    "TB",Builder
    "PB",Builder
    "EB",Builder
    "ZB",Builder
    "YB"]