{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DefaultSignatures#-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE UndecidableInstances #-}

{-| Module  : FiniteCategories
Description : A simple typeclass for things to be pretty printed.
Copyright   : Guillaume Sabbagh 2022
License     : GPL-3
Maintainer  : guillaumesabbagh@protonmail.com
Stability   : experimental
Portability : portable

A simple typeclass for things to be pretty printed. Categories objects and arrows should be pretty printable to be exported with graphviz.
Different objects should be pretty printed into different strings or the graphviz export might be wrong.
-}
module Math.IO.PrettyPrint
(
    PrettyPrint(..),
    pp,
    ppi,
    indentation,
    pprintFunction
)
where
    import              Data.List  (intercalate)
    import qualified    Data.Set                                            as Set
    import qualified    Data.WeakSet                                        as WSet
    import qualified    Data.WeakMap                                        as WMap
    import qualified    Data.Text                                           as Text
    import              Data.Int
    import              Data.Word
    import              Data.Simplifiable
    
    import              GHC.Generics
    
    import              Numeric.Natural
    
    -- | The typeclass of things that can be pretty printed.

    --

    -- 'pprint' takes a level of verbosity as its first argument from the less verbose 'pprint 0' to the most verbose 'pprint n'.

    class PrettyPrint a where
        -- | Pretty print an element of type 'a' with a given verbosity level. 0 is the less verbose possible.

        pprint :: Int -> a -> String
        
        -- | Pretty print with a given level of indentation an element of type 'a' with a given verbosity level. See 'pprintIndent' for usage.

        pprintWithIndentations :: Int -- ^ The current verbosity level

                     -> Int -- ^ Original verbosity level

                     -> String -- ^ The indentation used

                     -> a -- ^ The object to pretty print

                     -> String
        
        -- | Pretty print with indentation an element of type 'a' with a given verbosity level.

        pprintIndent :: Int -> a -> String
        pprintIndent Int
v a
a = Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations Int
v Int
v String
"| " a
a
        
        default pprint :: (Generic a, GPrettyPrint (Rep a)) => Int -> a -> String
        pprint Int
v a
a = Int -> Rep a Any -> String
forall a. Int -> Rep a a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v (a -> Rep a Any
forall x. a -> Rep a x
forall a x. Generic a => a -> Rep a x
from a
a)
        
        default pprintWithIndentations :: (Generic a, GPrettyPrint (Rep a)) => Int -> Int -> String -> a -> String
        pprintWithIndentations Int
cv Int
ov String
indent a
a = Int -> Int -> String -> Rep a Any -> String
forall a. Int -> Int -> String -> Rep a a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent (a -> Rep a Any
forall x. a -> Rep a x
forall a x. Generic a => a -> Rep a x
from a
a)
    
    -- | PutStrLn composed with pprint. Takes a verbosity level as its first argument.

    pp :: (PrettyPrint a) => Int -> a -> IO ()
    pp :: forall a. PrettyPrint a => Int -> a -> IO ()
pp Int
v a
a = String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint Int
v a
a
        
    -- | PutStrLn composed with pprintIndent. Takes a verbosity level as its first argument.

    ppi :: (PrettyPrint a) => Int -> a -> IO ()
    ppi :: forall a. PrettyPrint a => Int -> a -> IO ()
ppi Int
v a
a = String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprintIndent Int
v a
a
        
    -- | Add indentation at the begining of a string.

    indentation :: Int -> String -> String
    indentation :: Int -> String -> String
indentation Int
i String
s = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ Int -> String -> [String]
forall a. Int -> a -> [a]
replicate Int
i String
s
        
    class GPrettyPrint f where
        gpprint :: Int -> f a -> String
        gpprintWithIndentations :: Int -> Int -> String -> f a -> String
        
    instance GPrettyPrint U1 where
        gpprint :: forall a. Int -> U1 a -> String
gpprint Int
_ U1 a
U1 = []
        gpprintWithIndentations :: forall a. Int -> Int -> String -> U1 a -> String
gpprintWithIndentations Int
_ Int
_ String
_ U1 a
U1 = []
        
    instance (GPrettyPrint a, GPrettyPrint b) => GPrettyPrint (a :*: b) where
        -- gpprint 0 _ = "..."

        gpprint :: forall a. Int -> (:*:) a b a -> String
gpprint Int
v (a a
a :*: b a
b) = Int -> a a -> String
forall a. Int -> a a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v a a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> b a -> String
forall a. Int -> b a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v b a
b
        
        -- gpprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        gpprintWithIndentations :: forall a. Int -> Int -> String -> (:*:) a b a -> String
gpprintWithIndentations Int
cv Int
ov String
indent (a a
a :*: b a
b) = Int -> Int -> String -> a a -> String
forall a. Int -> Int -> String -> a a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent a a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Int -> String -> b a -> String
forall a. Int -> Int -> String -> b a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent b a
b
        
    instance (GPrettyPrint a, GPrettyPrint b) => GPrettyPrint (a :+: b) where
        -- gpprint 0 _ = "..."

        gpprint :: forall a. Int -> (:+:) a b a -> String
gpprint Int
v (L1 a a
a) = Int -> a a -> String
forall a. Int -> a a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v a a
a
        gpprint Int
v (R1 b a
b) = Int -> b a -> String
forall a. Int -> b a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v b a
b
        
        -- gpprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        gpprintWithIndentations :: forall a. Int -> Int -> String -> (:+:) a b a -> String
gpprintWithIndentations Int
cv Int
ov String
indent (L1 a a
a) = Int -> Int -> String -> a a -> String
forall a. Int -> Int -> String -> a a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent a a
a
        gpprintWithIndentations Int
cv Int
ov String
indent (R1 b a
b) = Int -> Int -> String -> b a -> String
forall a. Int -> Int -> String -> b a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent b a
b
        
        
    instance (GPrettyPrint a) => GPrettyPrint (S1 c a) where
        -- gpprint 0 _ = "..."

        gpprint :: forall a. Int -> S1 c a a -> String
gpprint Int
v (M1 a a
x) = Int -> a a -> String
forall a. Int -> a a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v a a
x
        
        -- gpprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        gpprintWithIndentations :: forall a. Int -> Int -> String -> S1 c a a -> String
gpprintWithIndentations Int
cv Int
ov String
indent (M1 a a
x) = Int -> Int -> String -> a a -> String
forall a. Int -> Int -> String -> a a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent a a
x
        
    instance (GPrettyPrint a) => GPrettyPrint (D1 c a) where
        -- gpprint 0 _ = "..."

        gpprint :: forall a. Int -> D1 c a a -> String
gpprint Int
v (M1 a a
x) = Int -> a a -> String
forall a. Int -> a a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v a a
x
        
        -- gpprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        gpprintWithIndentations :: forall a. Int -> Int -> String -> D1 c a a -> String
gpprintWithIndentations Int
cv Int
ov String
indent (M1 a a
x) = Int -> Int -> String -> a a -> String
forall a. Int -> Int -> String -> a a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent a a
x
    
    instance (Constructor c, GPrettyPrint a) => GPrettyPrint (C1 c a) where
        gpprint :: forall a. Int -> C1 c a a -> String
gpprint Int
v c :: C1 c a a
c@(M1 a a
x) 
            | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
innerString = C1 c a a -> String
forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t c f a -> String
conName C1 c a a
c
            | Bool
otherwise = C1 c a a -> String
forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t c f a -> String
conName C1 c a a
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"("String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
innerString String -> String -> String
forall a. [a] -> [a] -> [a]
++String
")"
            where
                innerString :: String
innerString = Int -> a a -> String
forall a. Int -> a a -> String
forall (f :: * -> *) a. GPrettyPrint f => Int -> f a -> String
gpprint Int
v a a
x
        
        gpprintWithIndentations :: forall a. Int -> Int -> String -> C1 c a a -> String
gpprintWithIndentations Int
0 Int
ov String
indent C1 c a a
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        gpprintWithIndentations Int
cv Int
ov String
indent c :: C1 c a a
c@(M1 a a
x)
            | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
innerString = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ C1 c a a -> String
forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t c f a -> String
conName C1 c a a
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"
            | Bool
otherwise = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ C1 c a a -> String
forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t c f a -> String
conName C1 c a a
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
innerString
            where
                innerString :: String
innerString = Int -> Int -> String -> a a -> String
forall a. Int -> Int -> String -> a a -> String
forall (f :: * -> *) a.
GPrettyPrint f =>
Int -> Int -> String -> f a -> String
gpprintWithIndentations Int
cv Int
ov String
indent a a
x

    instance (PrettyPrint a) => GPrettyPrint (K1 i a) where
        gpprint :: forall a. Int -> K1 i a a -> String
gpprint Int
0 K1 i a a
_ = String
"..."
        gpprint Int
v (K1 a
x) = Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
x
        
        gpprintWithIndentations :: forall a. Int -> Int -> String -> K1 i a a -> String
gpprintWithIndentations Int
0 Int
ov String
indent K1 i a a
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        gpprintWithIndentations Int
cv Int
ov String
indent (K1 a
x) = Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent a
x
        
        
        
        
        
        
    instance (PrettyPrint a) => PrettyPrint [a] where
        -- pprint 0 _ = "..."

        pprint :: Int -> [a] -> String
pprint Int
v [a]
xs = String
"[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," (Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
v) (a -> String) -> [a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
xs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]"
        
        pprintWithIndentations :: Int -> Int -> String -> [a] -> String
pprintWithIndentations Int
0 Int
ov String
indent [a]
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent [a]
xs = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"[\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
",\n" (String -> String
forall a. HasCallStack => [a] -> [a]
init (String -> String) -> (a -> String) -> a -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent  (a -> String) -> [a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
xs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]\n"
        
    instance (PrettyPrint a) => PrettyPrint (Maybe a) where
        -- pprint 0 _ = "..."

        pprint :: Int -> Maybe a -> String
pprint Int
_ Maybe a
Nothing = String
"Nothing"
        pprint Int
v (Just a
x) = Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint Int
v a
x
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Maybe a -> String
pprintWithIndentations Int
cv Int
ov String
indent Maybe a
Nothing = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Nothing\n"
        pprintWithIndentations Int
cv Int
ov String
indent (Just a
x) = Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations Int
cv Int
ov String
indent a
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"
        
    instance (PrettyPrint a, PrettyPrint b) => PrettyPrint (Either a b) where
        pprint :: Int -> Either a b -> String
pprint Int
0 Either a b
_ = String
"..."
        pprint Int
v (Left a
a) = Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint Int
v a
a
        pprint Int
v (Right b
a) = Int -> b -> String
forall a. PrettyPrint a => Int -> a -> String
pprint Int
v b
a
        
        pprintWithIndentations :: Int -> Int -> String -> Either a b -> String
pprintWithIndentations Int
0 Int
ov String
indent Either a b
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent (Left a
a) = Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations Int
cv Int
ov String
indent a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++String
"\n"
        pprintWithIndentations Int
cv Int
ov String
indent (Right b
a) = Int -> Int -> String -> b -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations Int
cv Int
ov String
indent b
a String -> String -> String
forall a. [a] -> [a] -> [a]
++String
"\n"
        
    instance (PrettyPrint a, PrettyPrint b) => PrettyPrint (a,b) where
        pprint :: Int -> (a, b) -> String
pprint Int
0 (a, b)
_ = String
"..."
        pprint Int
v (a
a,b
b) = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> b -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) b
b String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
        
        pprintWithIndentations :: Int -> Int -> String -> (a, b) -> String
pprintWithIndentations Int
0 Int
ov String
indent (a, b)
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent (a
a,b
b) = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"(\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent a
a) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Int -> String -> b -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent b
b String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")\n"
    
    instance (PrettyPrint a, PrettyPrint b, PrettyPrint c) => PrettyPrint (a,b,c) where
        pprint :: Int -> (a, b, c) -> String
pprint Int
0 (a, b, c)
_ = String
"..."
        pprint Int
v (a
a,b
b,c
c) = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> b -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) b
b String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> c -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) c
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
        
        pprintWithIndentations :: Int -> Int -> String -> (a, b, c) -> String
pprintWithIndentations Int
0 Int
ov String
indent (a, b, c)
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent (a
a,b
b,c
c) = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"(\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent a
a) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> b -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent b
b) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Int -> String -> c -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent c
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")\n"
        
    instance (PrettyPrint a, PrettyPrint b, PrettyPrint c, PrettyPrint d) => PrettyPrint (a,b,c,d) where
        pprint :: Int -> (a, b, c, d) -> String
pprint Int
0 (a, b, c, d)
_ = String
"..."
        pprint Int
v (a
a,b
b,c
c,d
d) = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> b -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) b
b String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> c -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) c
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> d -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) d
d String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
        
        pprintWithIndentations :: Int -> Int -> String -> (a, b, c, d) -> String
pprintWithIndentations Int
0 Int
ov String
indent (a, b, c, d)
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent (a
a,b
b,c
c,d
d) = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"(\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent a
a) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> b -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent b
b) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> c -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent c
c) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Int -> String -> d -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent d
d String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")\n"
        
    instance (PrettyPrint a, PrettyPrint b, PrettyPrint c, PrettyPrint d, PrettyPrint e) => PrettyPrint (a,b,c,d,e) where
        pprint :: Int -> (a, b, c, d, e) -> String
pprint Int
0 (a, b, c, d, e)
_ = String
"..."
        pprint Int
v (a
a,b
b,c
c,d
d,e
e) = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) a
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> b -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) b
b String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> c -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) c
c String -> String -> String
forall a. [a] -> [a] -> [a]
++String
","String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> d -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) d
d String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"," String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> e -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) e
e String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
        
        pprintWithIndentations :: Int -> Int -> String -> (a, b, c, d, e) -> String
pprintWithIndentations Int
0 Int
ov String
indent (a, b, c, d, e)
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent (a
a,b
b,c
c,d
d,e
e) = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"(\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent a
a) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> b -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent b
b) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> c -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent c
c) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. HasCallStack => [a] -> [a]
init (Int -> Int -> String -> d -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent d
d) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Int -> String -> e -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent e
e String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")\n"
        
    instance (PrettyPrint a) => PrettyPrint (Set.Set a) where
        -- pprint 0 _ = "..."

        pprint :: Int -> Set a -> String
pprint Int
v Set a
xs = String
"{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," (Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
v) (a -> String) -> [a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Set a -> [a]
forall a. Set a -> [a]
Set.toList Set a
xs)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
        
        pprintWithIndentations :: Int -> Int -> String -> Set a -> String
pprintWithIndentations Int
0 Int
ov String
indent Set a
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent Set a
xs = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"{\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
",\n" (String -> String
forall a. HasCallStack => [a] -> [a]
init (String -> String) -> (a -> String) -> a -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent  (a -> String) -> [a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Set a -> [a]
forall a. Set a -> [a]
Set.toList Set a
xs)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}\n"
        
        
    instance (PrettyPrint a, Eq a) => PrettyPrint (WSet.Set a) where
        -- pprint 0 _ = "..."

        pprint :: Int -> Set a -> String
pprint Int
v Set a
xs = String
"{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," (Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
v) (a -> String) -> [a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Set a -> [a]
forall a. Eq a => Set a -> [a]
WSet.setToList Set a
xs)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
        
        pprintWithIndentations :: Int -> Int -> String -> Set a -> String
pprintWithIndentations Int
0 Int
ov String
indent Set a
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent Set a
xs = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"{\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
",\n" (String -> String
forall a. HasCallStack => [a] -> [a]
init (String -> String) -> (a -> String) -> a -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> String -> a -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent  (a -> String) -> [a] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Set a -> [a]
forall a. Eq a => Set a -> [a]
WSet.setToList Set a
xs)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}\n"
        
    instance (PrettyPrint a, Eq a, PrettyPrint b, Eq b) => PrettyPrint (WMap.Map a b) where
        -- pprint 0 _ = "..."

        pprint :: Int -> Map a b -> String
pprint Int
verbosity Map a b
m = String
"{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," ((\(a
k,b
v) -> (Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
verbosity) a
k) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"->" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Int -> b -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
verbosity) b
v)) ((a, b) -> String) -> [(a, b)] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Map a b -> [(a, b)]
forall k v. Eq k => Map k v -> AssociationList k v
WMap.mapToList Map a b
m)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"
        
        pprintWithIndentations :: Int -> Int -> String -> Map a b -> String
pprintWithIndentations Int
0 Int
ov String
indent Map a b
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent Map a b
xs = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"{\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
",\n" (String -> String
forall a. HasCallStack => [a] -> [a]
init (String -> String) -> ((a, b) -> String) -> (a, b) -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> String -> (a, b) -> String
forall a. PrettyPrint a => Int -> Int -> String -> a -> String
pprintWithIndentations (Int
cvInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
ov String
indent  ((a, b) -> String) -> [(a, b)] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Map a b -> [(a, b)]
forall k v. Eq k => Map k v -> AssociationList k v
WMap.mapToList Map a b
xs)) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}\n"
        
    instance PrettyPrint Bool where
        -- pprint 0 = (const "...")

        pprint :: Int -> Bool -> String
pprint Int
_ = Bool -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Bool -> String
pprintWithIndentations Int
cv Int
ov String
indent Bool
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Bool -> String
forall a. Show a => a -> String
show Bool
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"
        
    instance PrettyPrint Char where
        -- pprint 0 = (const "...")

        pprint :: Int -> Char -> String
pprint Int
_ = (Char -> String -> String
forall a. a -> [a] -> [a]
:[])
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Char -> String
pprintWithIndentations Int
cv Int
ov String
indent Char
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
x] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"
        
    instance PrettyPrint Double where
        -- pprint 0 = (const "...")

        pprint :: Int -> Double -> String
pprint Int
_ = Double -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Double -> String
pprintWithIndentations Int
cv Int
ov String
indent Double
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Double -> String
forall a. Show a => a -> String
show Double
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Float where
        -- pprint 0 = (const "...")

        pprint :: Int -> Float -> String
pprint Int
_ = Float -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Float -> String
pprintWithIndentations Int
cv Int
ov String
indent Float
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Float -> String
forall a. Show a => a -> String
show Float
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Int where
        -- pprint 0 = (const "...")

        pprint :: Int -> Int -> String
pprint Int
_ = Int -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Int -> String
pprintWithIndentations Int
cv Int
ov String
indent Int
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Int8 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Int8 -> String
pprint Int
_ = Int8 -> String
forall a. Show a => a -> String
show  
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Int8 -> String
pprintWithIndentations Int
cv Int
ov String
indent Int8
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int8 -> String
forall a. Show a => a -> String
show Int8
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Int16 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Int16 -> String
pprint Int
_ = Int16 -> String
forall a. Show a => a -> String
show  
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Int16 -> String
pprintWithIndentations Int
cv Int
ov String
indent Int16
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int16 -> String
forall a. Show a => a -> String
show Int16
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Int32 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Int32 -> String
pprint Int
_ = Int32 -> String
forall a. Show a => a -> String
show  
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Int32 -> String
pprintWithIndentations Int
cv Int
ov String
indent Int32
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int32 -> String
forall a. Show a => a -> String
show Int32
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Int64 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Int64 -> String
pprint Int
_ = Int64 -> String
forall a. Show a => a -> String
show  
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Int64 -> String
pprintWithIndentations Int
cv Int
ov String
indent Int64
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int64 -> String
forall a. Show a => a -> String
show Int64
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Integer where
        -- pprint 0 = (const "...")

        pprint :: Int -> Integer -> String
pprint Int
_ = Integer -> String
forall a. Show a => a -> String
show  
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Integer -> String
pprintWithIndentations Int
cv Int
ov String
indent Integer
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    instance PrettyPrint Natural where
        -- pprint 0 = (const "...")

        pprint :: Int -> Natural -> String
pprint Int
_ = Natural -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Natural -> String
pprintWithIndentations Int
cv Int
ov String
indent Natural
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Natural -> String
forall a. Show a => a -> String
show Natural
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
            
    instance PrettyPrint Ordering where
        -- pprint 0 = (const "...")

        pprint :: Int -> Ordering -> String
pprint Int
_ = Ordering -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Ordering -> String
pprintWithIndentations Int
cv Int
ov String
indent Ordering
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Ordering -> String
forall a. Show a => a -> String
show Ordering
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
            
    instance PrettyPrint Word where
        -- pprint 0 = (const "...")

        pprint :: Int -> Word -> String
pprint Int
_ = Word -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Word -> String
pprintWithIndentations Int
cv Int
ov String
indent Word
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word -> String
forall a. Show a => a -> String
show Word
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
            
    instance PrettyPrint Word8 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Word8 -> String
pprint Int
_ = Word8 -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Word8 -> String
pprintWithIndentations Int
cv Int
ov String
indent Word8
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word8 -> String
forall a. Show a => a -> String
show Word8
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
            
    instance PrettyPrint Word16 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Word16 -> String
pprint Int
_ = Word16 -> String
forall a. Show a => a -> String
show
        
        pprintWithIndentations :: Int -> Int -> String -> Word16 -> String
pprintWithIndentations Int
0 Int
ov String
indent Word16
_ = Int -> String -> String
indentation Int
ov String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"...\n"
        pprintWithIndentations Int
cv Int
ov String
indent Word16
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word16 -> String
forall a. Show a => a -> String
show Word16
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
            
    instance PrettyPrint Word32 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Word32 -> String
pprint Int
_ = Word32 -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Word32 -> String
pprintWithIndentations Int
cv Int
ov String
indent Word32
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word32 -> String
forall a. Show a => a -> String
show Word32
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
            
    instance PrettyPrint Word64 where
        -- pprint 0 = (const "...")

        pprint :: Int -> Word64 -> String
pprint Int
_ = Word64 -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Word64 -> String
pprintWithIndentations Int
cv Int
ov String
indent Word64
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word64 -> String
forall a. Show a => a -> String
show Word64
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
            
    instance PrettyPrint () where
        -- pprint 0 = (const "...")

        pprint :: Int -> () -> String
pprint Int
_ = () -> String
forall a. Show a => a -> String
show
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> () -> String
pprintWithIndentations Int
cv Int
ov String
indent ()
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ () -> String
forall a. Show a => a -> String
show ()
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
               
    instance PrettyPrint Text.Text where
        -- pprint 0 = (const "...")

        pprint :: Int -> Text -> String
pprint Int
_ = Text -> String
Text.unpack
        
        -- pprintWithIndentations 0 ov indent _ = indentation ov indent ++ "...\n"

        pprintWithIndentations :: Int -> Int -> String -> Text -> String
pprintWithIndentations Int
cv Int
ov String
indent Text
x = Int -> String -> String
indentation (Int
ov Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cv) String
indent String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show Text
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" 
        
    
    -- | Pretty print a function on a specific domain.

    pprintFunction :: (PrettyPrint a, PrettyPrint b) =>
                   Int -> (a -> b) -> [a] -> String
    pprintFunction :: forall a b.
(PrettyPrint a, PrettyPrint b) =>
Int -> (a -> b) -> [a] -> String
pprintFunction Int
0 a -> b
_ [a]
_ = String
"..."
    pprintFunction Int
v a -> b
f [a]
xs = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" [Int -> a -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) a
x String -> String -> String
forall a. [a] -> [a] -> [a]
++String
" -> " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> b -> String
forall a. PrettyPrint a => Int -> a -> String
pprint (Int
vInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (a -> b
f a
x) | a
x <- [a]
xs]
    
    
    instance Simplifiable Text.Text where
        simplify :: Text -> Text
simplify = Text -> Text
forall a. a -> a
id