    -- | Pretty printing class, simlar to 'Show' but nicer looking.
    -- Note that the precedence level is a 'Rational' so there is an unlimited number of levels.
    -- Based on "Text.PrettyPrint.HughesPJ", which is re-exported.
    module Text.PrettyPrint.HughesPJClass(
        Pretty(..),
        PrettyLevel(..), prettyNormal,
        prettyShow, prettyParen,
        module Text.PrettyPrint.HughesPJ
        ) where
    import Text.PrettyPrint.HughesPJ
    import Data.Ratio

    -- | Level of detail in the pretty printed output.
    -- Level 0 is the least detail.
    newtype PrettyLevel = PrettyLevel Int
        deriving (PrettyLevel -> PrettyLevel -> Bool
    (PrettyLevel -> PrettyLevel -> Bool)
    -> (PrettyLevel -> PrettyLevel -> Bool) -> Eq PrettyLevel
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: PrettyLevel -> PrettyLevel -> Bool
    $c/= :: PrettyLevel -> PrettyLevel -> Bool
    == :: PrettyLevel -> PrettyLevel -> Bool
    $c== :: PrettyLevel -> PrettyLevel -> Bool
    Eq, Eq PrettyLevel
    Eq PrettyLevel =>
    (PrettyLevel -> PrettyLevel -> Ordering)
    -> (PrettyLevel -> PrettyLevel -> Bool)
    -> (PrettyLevel -> PrettyLevel -> Bool)
    -> (PrettyLevel -> PrettyLevel -> Bool)
    -> (PrettyLevel -> PrettyLevel -> Bool)
    -> (PrettyLevel -> PrettyLevel -> PrettyLevel)
    -> (PrettyLevel -> PrettyLevel -> PrettyLevel)
    -> Ord PrettyLevel
    PrettyLevel -> PrettyLevel -> Bool
    PrettyLevel -> PrettyLevel -> Ordering
    PrettyLevel -> PrettyLevel -> PrettyLevel
    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 :: PrettyLevel -> PrettyLevel -> PrettyLevel
    $cmin :: PrettyLevel -> PrettyLevel -> PrettyLevel
    max :: PrettyLevel -> PrettyLevel -> PrettyLevel
    $cmax :: PrettyLevel -> PrettyLevel -> PrettyLevel
    >= :: PrettyLevel -> PrettyLevel -> Bool
    $c>= :: PrettyLevel -> PrettyLevel -> Bool
    > :: PrettyLevel -> PrettyLevel -> Bool
    $c> :: PrettyLevel -> PrettyLevel -> Bool
    <= :: PrettyLevel -> PrettyLevel -> Bool
    $c<= :: PrettyLevel -> PrettyLevel -> Bool
    < :: PrettyLevel -> PrettyLevel -> Bool
    $c< :: PrettyLevel -> PrettyLevel -> Bool
    compare :: PrettyLevel -> PrettyLevel -> Ordering
    $ccompare :: PrettyLevel -> PrettyLevel -> Ordering
    $cp1Ord :: Eq PrettyLevel
    Ord, Int -> PrettyLevel -> ShowS
    [PrettyLevel] -> ShowS
    PrettyLevel -> String
    (Int -> PrettyLevel -> ShowS)
    -> (PrettyLevel -> String)
    -> ([PrettyLevel] -> ShowS)
    -> Show PrettyLevel
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [PrettyLevel] -> ShowS
    $cshowList :: [PrettyLevel] -> ShowS
    show :: PrettyLevel -> String
    $cshow :: PrettyLevel -> String
    showsPrec :: Int -> PrettyLevel -> ShowS
    $cshowsPrec :: Int -> PrettyLevel -> ShowS
    Show)

    prettyNormal :: PrettyLevel
    prettyNormal :: PrettyLevel
    prettyNormal = Int -> PrettyLevel
    PrettyLevel 0

    -- | Pretty printing class.  The precedence level is used in a similar way as in the 'Show' class.
    -- Minimal complete definition is either 'pPrintPrec' or 'pPrint'.
    class Pretty a where
        pPrintPrec :: PrettyLevel -> Rational -> a -> Doc
        pPrint :: a -> Doc
        pPrintList :: PrettyLevel -> [a] -> Doc

        pPrintPrec _ _ = a -> Doc
    forall a. Pretty a => a -> Doc
    pPrint
        pPrint = PrettyLevel -> Rational -> a -> Doc
    forall a. Pretty a => PrettyLevel -> Rational -> a -> Doc
    pPrintPrec PrettyLevel
    prettyNormal 0
        pPrintList l :: PrettyLevel
    l = Doc -> Doc
    brackets (Doc -> Doc) -> ([a] -> Doc) -> [a] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Doc] -> Doc
    fsep ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma ([Doc] -> [Doc]) -> ([a] -> [Doc]) -> [a] -> [Doc]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Doc) -> [a] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map (PrettyLevel -> Rational -> a -> Doc
    forall a. Pretty a => PrettyLevel -> Rational -> a -> Doc
    pPrintPrec PrettyLevel
    l 0)

    -- | Pretty print a value with the 'prettyNormal' level.
    prettyShow :: (Pretty a) => a -> String
    prettyShow :: a -> String
    prettyShow = Doc -> String
    render (Doc -> String) -> (a -> Doc) -> a -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Doc
    forall a. Pretty a => a -> Doc
    pPrint

    pPrint0 :: (Pretty a) => PrettyLevel -> a -> Doc
    pPrint0 :: PrettyLevel -> a -> Doc
    pPrint0 l :: PrettyLevel
    l = PrettyLevel -> Rational -> a -> Doc
    forall a. Pretty a => PrettyLevel -> Rational -> a -> Doc
    pPrintPrec PrettyLevel
    l 0

    appPrec :: Rational
    appPrec :: Rational
    appPrec = 10

    -- | Parenthesize an value if the boolean is true.
    prettyParen :: Bool -> Doc -> Doc
    prettyParen :: Bool -> Doc -> Doc
    prettyParen False = Doc -> Doc
    forall a. a -> a
    id
    prettyParen True = Doc -> Doc
    parens

    -- XXX Doesn't treat signs like Show.
    instance Pretty Int where pPrint :: Int -> Doc
    pPrint = Int -> Doc
    int
    instance Pretty Integer where pPrint :: Integer -> Doc
    pPrint = Integer -> Doc
    integer
    instance Pretty Float where pPrint :: Float -> Doc
    pPrint = Float -> Doc
    float
    instance Pretty Double where pPrint :: Double -> Doc
    pPrint = Double -> Doc
    double
    instance Pretty () where pPrint :: () -> Doc
    pPrint _ = String -> Doc
    text "()"
    instance Pretty Bool where pPrint :: Bool -> Doc
    pPrint = String -> Doc
    text (String -> Doc) -> (Bool -> String) -> Bool -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Bool -> String
    forall a. Show a => a -> String
    show
    instance Pretty Ordering where pPrint :: Ordering -> Doc
    pPrint = String -> Doc
    text (String -> Doc) -> (Ordering -> String) -> Ordering -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ordering -> String
    forall a. Show a => a -> String
    show
    instance Pretty Char where
        pPrint :: Char -> Doc
    pPrint = Char -> Doc
    char
        pPrintList :: PrettyLevel -> String -> Doc
    pPrintList _ = String -> Doc
    text (String -> Doc) -> ShowS -> String -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShowS
    forall a. Show a => a -> String
    show
    instance (Pretty a) => Pretty (Maybe a) where
        pPrintPrec :: PrettyLevel -> Rational -> Maybe a -> Doc
    pPrintPrec l :: PrettyLevel
    l p :: Rational
    p Nothing = String -> Doc
    text "Nothing"
        pPrintPrec l :: PrettyLevel
    l p :: Rational
    p (Just x :: a
    x) = Bool -> Doc -> Doc
    prettyParen (Rational
    p Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    appPrec) (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ String -> Doc
    text "Just" Doc -> Doc -> Doc
    <+> PrettyLevel -> Rational -> a -> Doc
    forall a. Pretty a => PrettyLevel -> Rational -> a -> Doc
    pPrintPrec PrettyLevel
    l (Rational
    appPrecRational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    +1) a
    x
    instance (Pretty a, Pretty b) => Pretty (Either a b) where
        pPrintPrec :: PrettyLevel -> Rational -> Either a b -> Doc
    pPrintPrec l :: PrettyLevel
    l p :: Rational
    p (Left x :: a
    x) = Bool -> Doc -> Doc
    prettyParen (Rational
    p Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    appPrec) (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ String -> Doc
    text "Left" Doc -> Doc -> Doc
    <+> PrettyLevel -> Rational -> a -> Doc
    forall a. Pretty a => PrettyLevel -> Rational -> a -> Doc
    pPrintPrec PrettyLevel
    l (Rational
    appPrecRational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    +1) a
    x
        pPrintPrec l :: PrettyLevel
    l p :: Rational
    p (Right x :: b
    x) = Bool -> Doc -> Doc
    prettyParen (Rational
    p Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    > Rational
    appPrec) (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ String -> Doc
    text "Right" Doc -> Doc -> Doc
    <+> PrettyLevel -> Rational -> b -> Doc
    forall a. Pretty a => PrettyLevel -> Rational -> a -> Doc
    pPrintPrec PrettyLevel
    l (Rational
    appPrecRational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    +1) b
    x

    instance (Pretty a) => Pretty [a] where
        pPrintPrec :: PrettyLevel -> Rational -> [a] -> Doc
    pPrintPrec l :: PrettyLevel
    l _ xs :: [a]
    xs = PrettyLevel -> [a] -> Doc
    forall a. Pretty a => PrettyLevel -> [a] -> Doc
    pPrintList PrettyLevel
    l [a]
    xs

    instance (Pretty a, Pretty b) => Pretty (a, b) where
        pPrintPrec :: PrettyLevel -> Rational -> (a, b) -> Doc
    pPrintPrec l :: PrettyLevel
    l _ (a :: a
    a, b :: b
    b) =
            Doc -> Doc
    parens (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    fsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma [PrettyLevel -> a -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l a
    a, PrettyLevel -> b -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l b
    b]

    instance (Pretty a, Pretty b, Pretty c) => Pretty (a, b, c) where
        pPrintPrec :: PrettyLevel -> Rational -> (a, b, c) -> Doc
    pPrintPrec l :: PrettyLevel
    l _ (a :: a
    a, b :: b
    b, c :: c
    c) =
            Doc -> Doc
    parens (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    fsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma [PrettyLevel -> a -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l a
    a, PrettyLevel -> b -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l b
    b, PrettyLevel -> c -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l c
    c]

    instance (Pretty a, Pretty b, Pretty c, Pretty d) => Pretty (a, b, c, d) where
        pPrintPrec :: PrettyLevel -> Rational -> (a, b, c, d) -> Doc
    pPrintPrec l :: PrettyLevel
    l _ (a :: a
    a, b :: b
    b, c :: c
    c, d :: d
    d) =
            Doc -> Doc
    parens (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    fsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma [PrettyLevel -> a -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l a
    a, PrettyLevel -> b -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l b
    b, PrettyLevel -> c -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l c
    c, PrettyLevel -> d -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l d
    d]

    instance (Pretty a, Pretty b, Pretty c, Pretty d, Pretty e) => Pretty (a, b, c, d, e) where
        pPrintPrec :: PrettyLevel -> Rational -> (a, b, c, d, e) -> Doc
    pPrintPrec l :: PrettyLevel
    l _ (a :: a
    a, b :: b
    b, c :: c
    c, d :: d
    d, e :: e
    e) =
            Doc -> Doc
    parens (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    fsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma [PrettyLevel -> a -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l a
    a, PrettyLevel -> b -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l b
    b, PrettyLevel -> c -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l c
    c, PrettyLevel -> d -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l d
    d, PrettyLevel -> e -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l e
    e]

    instance (Pretty a, Pretty b, Pretty c, Pretty d, Pretty e, Pretty f) => Pretty (a, b, c, d, e, f) where
        pPrintPrec :: PrettyLevel -> Rational -> (a, b, c, d, e, f) -> Doc
    pPrintPrec l :: PrettyLevel
    l _ (a :: a
    a, b :: b
    b, c :: c
    c, d :: d
    d, e :: e
    e, f :: f
    f) =
            Doc -> Doc
    parens (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    fsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma [PrettyLevel -> a -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l a
    a, PrettyLevel -> b -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l b
    b, PrettyLevel -> c -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l c
    c, PrettyLevel -> d -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l d
    d, PrettyLevel -> e -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l e
    e, PrettyLevel -> f -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l f
    f]

    instance (Pretty a, Pretty b, Pretty c, Pretty d, Pretty e, Pretty f, Pretty g) =>
             Pretty (a, b, c, d, e, f, g) where
        pPrintPrec :: PrettyLevel -> Rational -> (a, b, c, d, e, f, g) -> Doc
    pPrintPrec l :: PrettyLevel
    l _ (a :: a
    a, b :: b
    b, c :: c
    c, d :: d
    d, e :: e
    e, f :: f
    f, g :: g
    g) =
            Doc -> Doc
    parens (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    fsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma [PrettyLevel -> a -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l a
    a, PrettyLevel -> b -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l b
    b, PrettyLevel -> c -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l c
    c, PrettyLevel -> d -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l d
    d, PrettyLevel -> e -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l e
    e, PrettyLevel -> f -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l f
    f, PrettyLevel -> g -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l g
    g]

    instance (Pretty a, Pretty b, Pretty c, Pretty d, Pretty e, Pretty f, Pretty g, Pretty h) =>
             Pretty (a, b, c, d, e, f, g, h) where
        pPrintPrec :: PrettyLevel -> Rational -> (a, b, c, d, e, f, g, h) -> Doc
    pPrintPrec l :: PrettyLevel
    l _ (a :: a
    a, b :: b
    b, c :: c
    c, d :: d
    d, e :: e
    e, f :: f
    f, g :: g
    g, h :: h
    h) =
            Doc -> Doc
    parens (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    fsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma [PrettyLevel -> a -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l a
    a, PrettyLevel -> b -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l b
    b, PrettyLevel -> c -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l c
    c, PrettyLevel -> d -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l d
    d, PrettyLevel -> e -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l e
    e, PrettyLevel -> f -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l f
    f, PrettyLevel -> g -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l g
    g, PrettyLevel -> h -> Doc
    forall a. Pretty a => PrettyLevel -> a -> Doc
    pPrint0 PrettyLevel
    l h
    h]