{-# LANGUAGE CPP                #-}
{-# LANGUAGE FlexibleContexts   #-}
{-# LANGUAGE FlexibleInstances  #-}
{-# LANGUAGE OverloadedStrings  #-}

module Language.Fixpoint.Types.PrettyPrint where

import           Debug.Trace               (trace)
import           Text.PrettyPrint.HughesPJ.Compat
import qualified Text.PrettyPrint.Boxes as B
import qualified Data.HashMap.Strict as M
import qualified Data.HashSet        as S
import qualified Data.List           as L
import           Language.Fixpoint.Misc
import           Data.Hashable
#if !MIN_VERSION_base(4,14,0)
import           Data.Semigroup (Semigroup (..))
#endif

import qualified Data.Text as T

traceFix     ::  (Fixpoint a) => String -> a -> a
traceFix :: String -> a -> a
traceFix String
s a
x = String -> a -> a
forall a. String -> a -> a
trace (String
"\nTrace: [" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"] : " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Fixpoint a => a -> String
showFix a
x) a
x

------------------------------------------------------------------
class Fixpoint a where
  toFix    :: a -> Doc
  simplify :: a -> a
  simplify =  a -> a
forall a. a -> a
id

showFix :: (Fixpoint a) => a -> String
showFix :: a -> String
showFix =  Doc -> String
render (Doc -> String) -> (a -> Doc) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc
forall a. Fixpoint a => a -> Doc
toFix

instance (Ord a, Hashable a, Fixpoint a) => Fixpoint (S.HashSet a) where
  toFix :: HashSet a -> Doc
toFix HashSet a
xs = Doc -> Doc
brackets (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
sep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> [Doc] -> [Doc]
punctuate Doc
";" (a -> Doc
forall a. Fixpoint a => a -> Doc
toFix (a -> Doc) -> [a] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a] -> [a]
forall a. Ord a => [a] -> [a]
L.sort (HashSet a -> [a]
forall a. HashSet a -> [a]
S.toList HashSet a
xs))
  simplify :: HashSet a -> HashSet a
simplify = [a] -> HashSet a
forall a. (Eq a, Hashable a) => [a] -> HashSet a
S.fromList ([a] -> HashSet a) -> (HashSet a -> [a]) -> HashSet a -> HashSet a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map a -> a
forall a. Fixpoint a => a -> a
simplify ([a] -> [a]) -> (HashSet a -> [a]) -> HashSet a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashSet a -> [a]
forall a. HashSet a -> [a]
S.toList

instance Fixpoint () where
  toFix :: () -> Doc
toFix ()
_ = Doc
"()"

instance Fixpoint a => Fixpoint (Maybe a) where
  toFix :: Maybe a -> Doc
toFix    = Doc -> (a -> Doc) -> Maybe a -> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc
"Nothing" ((Doc
"Just" Doc -> Doc -> Doc
<+>) (Doc -> Doc) -> (a -> Doc) -> a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc
forall a. Fixpoint a => a -> Doc
toFix)
  simplify :: Maybe a -> Maybe a
simplify = (a -> a) -> Maybe a -> Maybe a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Fixpoint a => a -> a
simplify

instance Fixpoint a => Fixpoint [a] where
  toFix :: [a] -> Doc
toFix [a]
xs = Doc -> Doc
brackets (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
sep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> [Doc] -> [Doc]
punctuate Doc
";" ((a -> Doc) -> [a] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Doc
forall a. Fixpoint a => a -> Doc
toFix [a]
xs)
  simplify :: [a] -> [a]
simplify = (a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map a -> a
forall a. Fixpoint a => a -> a
simplify

instance (Fixpoint a, Fixpoint b) => Fixpoint (a,b) where
  toFix :: (a, b) -> Doc
toFix   (a
x,b
y)  = a -> Doc
forall a. Fixpoint a => a -> Doc
toFix a
x Doc -> Doc -> Doc
<+> Doc
":" Doc -> Doc -> Doc
<+> b -> Doc
forall a. Fixpoint a => a -> Doc
toFix b
y
  simplify :: (a, b) -> (a, b)
simplify (a
x,b
y) = (a -> a
forall a. Fixpoint a => a -> a
simplify a
x, b -> b
forall a. Fixpoint a => a -> a
simplify b
y)

instance (Fixpoint a, Fixpoint b, Fixpoint c) => Fixpoint (a,b,c) where
  toFix :: (a, b, c) -> Doc
toFix   (a
x,b
y,c
z)  = a -> Doc
forall a. Fixpoint a => a -> Doc
toFix a
x Doc -> Doc -> Doc
<+> Doc
":" Doc -> Doc -> Doc
<+> b -> Doc
forall a. Fixpoint a => a -> Doc
toFix b
y Doc -> Doc -> Doc
<+> Doc
":" Doc -> Doc -> Doc
<+> c -> Doc
forall a. Fixpoint a => a -> Doc
toFix  c
z
  simplify :: (a, b, c) -> (a, b, c)
simplify (a
x,b
y,c
z) = (a -> a
forall a. Fixpoint a => a -> a
simplify a
x, b -> b
forall a. Fixpoint a => a -> a
simplify b
y,c -> c
forall a. Fixpoint a => a -> a
simplify c
z)

instance Fixpoint Bool where
  toFix :: Bool -> Doc
toFix Bool
True  = Doc
"True"
  toFix Bool
False = Doc
"False"
  simplify :: Bool -> Bool
simplify Bool
z  = Bool
z

instance Fixpoint Int where
  toFix :: Int -> Doc
toFix = Int -> Doc
forall a. Show a => a -> Doc
tshow

instance Fixpoint Integer where
  toFix :: Integer -> Doc
toFix = Integer -> Doc
integer

instance Fixpoint Double where
  toFix :: Double -> Doc
toFix = Double -> Doc
double

------------------------------------------------------------------
data Tidy = Lossy | Full deriving (Tidy -> Tidy -> Bool
(Tidy -> Tidy -> Bool) -> (Tidy -> Tidy -> Bool) -> Eq Tidy
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Tidy -> Tidy -> Bool
$c/= :: Tidy -> Tidy -> Bool
== :: Tidy -> Tidy -> Bool
$c== :: Tidy -> Tidy -> Bool
Eq, Eq Tidy
Eq Tidy
-> (Tidy -> Tidy -> Ordering)
-> (Tidy -> Tidy -> Bool)
-> (Tidy -> Tidy -> Bool)
-> (Tidy -> Tidy -> Bool)
-> (Tidy -> Tidy -> Bool)
-> (Tidy -> Tidy -> Tidy)
-> (Tidy -> Tidy -> Tidy)
-> Ord Tidy
Tidy -> Tidy -> Bool
Tidy -> Tidy -> Ordering
Tidy -> Tidy -> Tidy
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 :: Tidy -> Tidy -> Tidy
$cmin :: Tidy -> Tidy -> Tidy
max :: Tidy -> Tidy -> Tidy
$cmax :: Tidy -> Tidy -> Tidy
>= :: Tidy -> Tidy -> Bool
$c>= :: Tidy -> Tidy -> Bool
> :: Tidy -> Tidy -> Bool
$c> :: Tidy -> Tidy -> Bool
<= :: Tidy -> Tidy -> Bool
$c<= :: Tidy -> Tidy -> Bool
< :: Tidy -> Tidy -> Bool
$c< :: Tidy -> Tidy -> Bool
compare :: Tidy -> Tidy -> Ordering
$ccompare :: Tidy -> Tidy -> Ordering
$cp1Ord :: Eq Tidy
Ord)

-- | Implement either `pprintTidy` or `pprintPrec`
class PPrint a where

  pprintTidy :: Tidy -> a -> Doc
  pprintTidy = Int -> Tidy -> a -> Doc
forall a. PPrint a => Int -> Tidy -> a -> Doc
pprintPrec Int
0

  pprintPrec :: Int -> Tidy -> a -> Doc
  pprintPrec Int
_ = Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy

-- | Top-level pretty printer
pprint :: (PPrint a) => a -> Doc
pprint :: a -> Doc
pprint = Int -> Tidy -> a -> Doc
forall a. PPrint a => Int -> Tidy -> a -> Doc
pprintPrec Int
0 Tidy
Full

showpp :: (PPrint a) => a -> String
showpp :: a -> String
showpp = Doc -> String
render (Doc -> String) -> (a -> Doc) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc
forall a. PPrint a => a -> Doc
pprint

showTable :: (PPrint k, PPrint v) => Tidy -> [(k, v)] -> String
showTable :: Tidy -> [(k, v)] -> String
showTable Tidy
k = Doc -> String
render (Doc -> String) -> ([(k, v)] -> Doc) -> [(k, v)] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tidy -> [(k, v)] -> Doc
forall k v. (PPrint k, PPrint v) => Tidy -> [(k, v)] -> Doc
pprintKVs Tidy
k

-- | Please do not alter this.
tracepp :: (PPrint a) => String -> a -> a
tracepp :: String -> a -> a
tracepp String
s a
x = String -> a -> a
forall a. String -> a -> a
trace (String
"\nTrace: [" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"] : " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. PPrint a => a -> String
showpp a
x) a
x

notracepp :: (PPrint a) => String -> a -> a
notracepp :: String -> a -> a
notracepp String
_ a
x = a
x

instance PPrint Doc where
  pprintTidy :: Tidy -> Doc -> Doc
pprintTidy Tidy
_ = Doc -> Doc
forall a. a -> a
id

instance (PPrint a, PPrint b) => PPrint (Either a b) where 
  pprintTidy :: Tidy -> Either a b -> Doc
pprintTidy Tidy
k (Left  a
a) = Doc
"Left"  Doc -> Doc -> Doc
<+> Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k a
a
  pprintTidy Tidy
k (Right b
b) = Doc
"Right" Doc -> Doc -> Doc
<+> Tidy -> b -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k b
b

instance PPrint a => PPrint (Maybe a) where
  pprintTidy :: Tidy -> Maybe a -> Doc
pprintTidy Tidy
k = Doc -> (a -> Doc) -> Maybe a -> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc
"Nothing" ((Doc
"Just" Doc -> Doc -> Doc
<+>) (Doc -> Doc) -> (a -> Doc) -> a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k)

instance PPrint a => PPrint [a] where
  pprintTidy :: Tidy -> [a] -> Doc
pprintTidy Tidy
k = Doc -> Doc
brackets (Doc -> Doc) -> ([a] -> Doc) -> [a] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Doc] -> Doc
sep ([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 (Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k)

instance PPrint a => PPrint (S.HashSet a) where
  pprintTidy :: Tidy -> HashSet a -> Doc
pprintTidy Tidy
k = Tidy -> [a] -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k ([a] -> Doc) -> (HashSet a -> [a]) -> HashSet a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashSet a -> [a]
forall a. HashSet a -> [a]
S.toList

instance (PPrint a, PPrint b) => PPrint (M.HashMap a b) where
  pprintTidy :: Tidy -> HashMap a b -> Doc
pprintTidy Tidy
k = Tidy -> [(a, b)] -> Doc
forall k v. (PPrint k, PPrint v) => Tidy -> [(k, v)] -> Doc
pprintKVs Tidy
k ([(a, b)] -> Doc)
-> (HashMap a b -> [(a, b)]) -> HashMap a b -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap a b -> [(a, b)]
forall k v. HashMap k v -> [(k, v)]
M.toList

pprintKVs   :: (PPrint k, PPrint v) => Tidy -> [(k, v)] -> Doc
pprintKVs :: Tidy -> [(k, v)] -> Doc
pprintKVs Tidy
t = [Doc] -> Doc
vcat ([Doc] -> Doc) -> ([(k, v)] -> [Doc]) -> [(k, v)] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> [Doc] -> [Doc]
punctuate Doc
"\n" ([Doc] -> [Doc]) -> ([(k, v)] -> [Doc]) -> [(k, v)] -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((k, v) -> Doc) -> [(k, v)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (k, v) -> Doc
forall a a. (PPrint a, PPrint a) => (a, a) -> Doc
pp1
  where
    pp1 :: (a, a) -> Doc
pp1 (a
x,a
y) = Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
t a
x Doc -> Doc -> Doc
<+> Doc
":=" Doc -> Doc -> Doc
<+> Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
t a
y

instance (PPrint a, PPrint b, PPrint c) => PPrint (a, b, c) where
  pprintTidy :: Tidy -> (a, b, c) -> Doc
pprintTidy Tidy
k (a
x, b
y, c
z)  = Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k a
x Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                     Tidy -> b -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k b
y Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                     Tidy -> c -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k c
z



instance (PPrint a, PPrint b, PPrint c, PPrint d) => PPrint (a, b, c, d) where
  pprintTidy :: Tidy -> (a, b, c, d) -> Doc
pprintTidy Tidy
k (a
w, b
x, c
y, d
z)  = Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k a
w Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                        Tidy -> b -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k b
x Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                        Tidy -> c -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k c
y Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                        Tidy -> d -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k d
z

instance (PPrint a, PPrint b, PPrint c, PPrint d, PPrint e) => PPrint (a, b, c, d, e) where
  pprintTidy :: Tidy -> (a, b, c, d, e) -> Doc
pprintTidy Tidy
k (a
v, b
w, c
x, d
y, e
z)  = Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k a
v Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                           Tidy -> b -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k b
w Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                           Tidy -> c -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k c
x Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                           Tidy -> d -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k d
y Doc -> Doc -> Doc
<-> Doc
"," Doc -> Doc -> Doc
<+>
                                           Tidy -> e -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k e
z



instance (PPrint a, PPrint b) => PPrint (a,b) where
  pprintTidy :: Tidy -> (a, b) -> Doc
pprintTidy Tidy
k (a
x, b
y)  = Tidy -> a -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k a
x Doc -> Doc -> Doc
<+> Doc
":" Doc -> Doc -> Doc
<+> Tidy -> b -> Doc
forall a. PPrint a => Tidy -> a -> Doc
pprintTidy Tidy
k b
y

instance PPrint Bool where
  pprintTidy :: Tidy -> Bool -> Doc
pprintTidy Tidy
_ = 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 PPrint Float where
  pprintTidy :: Tidy -> Float -> Doc
pprintTidy Tidy
_ = String -> Doc
text (String -> Doc) -> (Float -> String) -> Float -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> String
forall a. Show a => a -> String
show

instance PPrint () where
  pprintTidy :: Tidy -> () -> Doc
pprintTidy Tidy
_ = String -> Doc
text (String -> Doc) -> (() -> String) -> () -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. () -> String
forall a. Show a => a -> String
show

#if !(defined(MIN_VERSION_GLASGOW_HASKELL) && (MIN_VERSION_GLASGOW_HASKELL(8,0,1,1)))
instance PPrint String where
  pprintTidy _ = text
#endif

instance PPrint Int where
  pprintTidy :: Tidy -> Int -> Doc
pprintTidy Tidy
_ = Int -> Doc
forall a. Show a => a -> Doc
tshow

instance PPrint Integer where
  pprintTidy :: Tidy -> Integer -> Doc
pprintTidy Tidy
_ = Integer -> Doc
integer

instance PPrint T.Text where
  pprintTidy :: Tidy -> Text -> Doc
pprintTidy Tidy
_ = String -> Doc
text (String -> Doc) -> (Text -> String) -> Text -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack

newtype DocTable = DocTable [(Doc, Doc)]

instance Semigroup DocTable where
  DocTable [(Doc, Doc)]
t1 <> :: DocTable -> DocTable -> DocTable
<> DocTable [(Doc, Doc)]
t2 = [(Doc, Doc)] -> DocTable
DocTable ([(Doc, Doc)]
t1 [(Doc, Doc)] -> [(Doc, Doc)] -> [(Doc, Doc)]
forall a. [a] -> [a] -> [a]
++ [(Doc, Doc)]
t2)

instance Monoid DocTable where
  mempty :: DocTable
mempty  = [(Doc, Doc)] -> DocTable
DocTable []
  mappend :: DocTable -> DocTable -> DocTable
mappend = DocTable -> DocTable -> DocTable
forall a. Semigroup a => a -> a -> a
(<>)

class PTable a where
  ptable :: a -> DocTable

instance PPrint DocTable where
  pprintTidy :: Tidy -> DocTable -> Doc
pprintTidy Tidy
_ (DocTable [(Doc, Doc)]
kvs) = Box -> Doc
boxDoc (Box -> Doc) -> Box -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> Alignment -> [Box] -> Box
forall (f :: * -> *).
Foldable f =>
Int -> Alignment -> f Box -> Box
B.hsep Int
1 Alignment
B.left [Box
ks', Box
cs', Box
vs']
    where
      ([Doc]
ks, [Doc]
vs)                = [(Doc, Doc)] -> ([Doc], [Doc])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Doc, Doc)]
kvs
      n :: Int
n                       = [(Doc, Doc)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Doc, Doc)]
kvs
      ks' :: Box
ks'                     = Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
B.vcat Alignment
B.left  ([Box] -> Box) -> [Box] -> Box
forall a b. (a -> b) -> a -> b
$ Doc -> Box
docBox (Doc -> Box) -> [Doc] -> [Box]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Doc]
ks
      vs' :: Box
vs'                     = Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
B.vcat Alignment
B.right ([Box] -> Box) -> [Box] -> Box
forall a b. (a -> b) -> a -> b
$ Doc -> Box
docBox (Doc -> Box) -> [Doc] -> [Box]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Doc]
vs
      cs' :: Box
cs'                     = Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
B.vcat Alignment
B.left  ([Box] -> Box) -> [Box] -> Box
forall a b. (a -> b) -> a -> b
$ Int -> Box -> [Box]
forall a. Int -> a -> [a]
replicate Int
n (Box -> [Box]) -> Box -> [Box]
forall a b. (a -> b) -> a -> b
$ String -> Box
B.text String
":"

boxHSep :: Doc -> Doc -> Doc
boxHSep :: Doc -> Doc -> Doc
boxHSep Doc
d1 Doc
d2 = Box -> Doc
boxDoc (Box -> Doc) -> Box -> Doc
forall a b. (a -> b) -> a -> b
$ Alignment -> [Box] -> Box
forall (f :: * -> *). Foldable f => Alignment -> f Box -> Box
B.hcat Alignment
B.top [Doc -> Box
docBox Doc
d1, Doc -> Box
docBox Doc
d2]

boxDoc :: B.Box -> Doc
boxDoc :: Box -> Doc
boxDoc = String -> Doc
text (String -> Doc) -> (Box -> String) -> Box -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Box -> String
B.render

docBox :: Doc -> B.Box
docBox :: Doc -> Box
docBox = String -> Box
B.text (String -> Box) -> (Doc -> String) -> Doc -> Box
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> String
render