{-# LANGUAGE TypeFamilies #-}
-- | Silkscreen is a library of pretty-printing transformers built around the <https://hackage.haskell.org/package/prettyprinter prettyprinter> package. This module defines the core 'Printer' abstraction and a few instances.
--
-- More documentation can be found in <https://hackage.haskell.org/package/prettyprinter/docs/Prettyprinter.html Prettyprinter>.
module Silkscreen
( -- * Printing
  Printer(..)
  -- * Combinators
, pretty
, prettyList
, annotate
, group
, flatAlt
, align
, hang
, indent
, nest
, concatWith
, hsep
, vsep
, fillSep
, sep
, hcat
, vcat
, fillCat
, cat
, punctuate
, width
, fill
, fillBreak
, P.plural
, enclose
, encloseSep
, list
, tupled
, surround
, (<+>)
, (</>)
  -- ** Conditional combinators
, parensIf
  -- * Symbols
, space
, line
, line'
, softline
, softline'
, hardline
, lparen
, rparen
, lbracket
, rbracket
, lbrace
, rbrace
, langle
, rangle
, squote
, dquote
, semi
, comma
, colon
, dot
, slash
, backslash
, equals
, pipe
  -- * Re-exports
, P.Pretty
, P.PageWidth(..)
) where

import           Control.Applicative (liftA2)
import           Data.Semigroup (stimes)
import qualified Prettyprinter as P

-- | A 'Printer' abstracts pretty-printing to allow the composition of behaviours such as e.g. rainbow parentheses, precedence handling, and so forth.
class Monoid p => Printer p where
  -- | The type of annotations supported by the printer.
  --
  -- We provide this as a type family instead of defining 'Printer' over kind @Type -> Type@ in order to allow instances to constrain annotations.
  type Ann p

  -- | Lift a 'P.Doc' to a 'Printer'.
  liftDoc0 :: P.Doc (Ann p) -> p

  -- | Lift a unary function on 'P.Doc' to a 'Printer'.
  liftDoc1 :: (P.Doc (Ann p) -> P.Doc (Ann p)) -> (p -> p)

  -- | Lift a binary function on 'P.Doc' to a 'Printer'.
  liftDoc2 :: (P.Doc (Ann p) -> P.Doc (Ann p) -> P.Doc (Ann p)) -> (p -> p -> p)

  -- | @'enclosing' l r x@ wraps @x@ in @l@ and @r@.
  --
  -- Distinct from 'enclose' (which is not overloaded) so that 'enclose' remains available as a convenience for appending documents without whatever extra semantics are implied by any particular 'Printer' (rainbow precedences, resetting precedence, etc.).
  --
  -- Overloadable to support e.g. rainbow parentheses.
  enclosing :: p -> p -> p -> p
  enclosing = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclose


  -- | Wrap the argument in single quotes.
  --
  -- The default definition is given in terms of 'enclosing'. Overloadable to support e.g. rainbow quotes (or disabling of same, if desired).
  squotes :: p -> p
  squotes = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclosing p
forall p. Printer p => p
squote p
forall p. Printer p => p
squote

  -- | Wrap the argument in double quotes.
  --
  -- The default definition is given in terms of 'enclosing'. Overloadable to support e.g. rainbow quotes (or disabling of same, if desired).
  dquotes :: p -> p
  dquotes = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclosing p
forall p. Printer p => p
dquote p
forall p. Printer p => p
dquote

  -- | Parenthesize the argument.
  --
  -- The default definition is given in terms of 'enclosing'. Overloadable to support e.g. rainbow parentheses (or disabling of same, if desired).
  parens :: p -> p
  parens = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclosing p
forall p. Printer p => p
lparen p
forall p. Printer p => p
rparen

  -- | Wrap the argument in brackets.
  --
  -- The default definition is given in terms of 'enclosing'. Overloadable to support e.g. rainbow brackets (or disabling of same, if desired).
  brackets :: p -> p
  brackets = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclosing p
forall p. Printer p => p
lbracket p
forall p. Printer p => p
rbracket

  -- | Wrap the argument in braces.
  --
  -- The default definition is given in terms of 'enclosing'. Overloadable to support e.g. rainbow braces (or disabling of same, if desired).
  braces :: p -> p
  braces = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclosing p
forall p. Printer p => p
lbrace p
forall p. Printer p => p
rbrace

  -- | Wrap the argument in angle brackets.
  --
  -- The default definition is given in terms of 'enclosing'. Overloadable to support e.g. rainbow angle brackets (or disabling of same, if desired).
  angles :: p -> p
  angles = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclosing p
forall p. Printer p => p
langle p
forall p. Printer p => p
rangle


  column :: (Int -> p) -> p

  nesting :: (Int -> p) -> p

  pageWidth :: (P.PageWidth -> p) -> p


-- Non-primitive combinators

-- | Pretty-print a value using the 'P.Pretty' instance for its type.
pretty :: (Printer p, P.Pretty t) => t -> p
pretty :: t -> p
pretty = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 (Doc (Ann p) -> p) -> (t -> Doc (Ann p)) -> t -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> Doc (Ann p)
forall a ann. Pretty a => a -> Doc ann
P.pretty

prettyList :: (Printer p, P.Pretty t) => [t] -> p
prettyList :: [t] -> p
prettyList = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 (Doc (Ann p) -> p) -> ([t] -> Doc (Ann p)) -> [t] -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [t] -> Doc (Ann p)
forall a ann. Pretty a => [a] -> Doc ann
P.prettyList


-- | Annotate a 'Printer' with an @'Ann' p@.
annotate :: Printer p => Ann p -> p -> p
annotate :: Ann p -> p -> p
annotate = (Doc (Ann p) -> Doc (Ann p)) -> p -> p
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 ((Doc (Ann p) -> Doc (Ann p)) -> p -> p)
-> (Ann p -> Doc (Ann p) -> Doc (Ann p)) -> Ann p -> p -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ann p -> Doc (Ann p) -> Doc (Ann p)
forall ann. ann -> Doc ann -> Doc ann
P.annotate


-- | Try to unwrap the argument, if it will fit.
group :: Printer p => p -> p
group :: p -> p
group = (Doc (Ann p) -> Doc (Ann p)) -> p -> p
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 Doc (Ann p) -> Doc (Ann p)
forall ann. Doc ann -> Doc ann
P.group

-- | Print the first argument by default, or the second when an enclosing 'group' flattens it.
flatAlt :: Printer p => p -> p -> p
flatAlt :: p -> p -> p
flatAlt = (Doc (Ann p) -> Doc (Ann p) -> Doc (Ann p)) -> p -> p -> p
forall p.
Printer p =>
(Doc (Ann p) -> Doc (Ann p) -> Doc (Ann p)) -> p -> p -> p
liftDoc2 Doc (Ann p) -> Doc (Ann p) -> Doc (Ann p)
forall ann. Doc ann -> Doc ann -> Doc ann
P.flatAlt


-- | Indent lines in the argument to the current column.
align :: Printer p => p -> p
align :: p -> p
align = (Doc (Ann p) -> Doc (Ann p)) -> p -> p
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 Doc (Ann p) -> Doc (Ann p)
forall ann. Doc ann -> Doc ann
P.align

-- | Indent following lines in the argument to the current column + some delta.
hang :: Printer p => Int -> p -> p
hang :: Int -> p -> p
hang = (Doc (Ann p) -> Doc (Ann p)) -> p -> p
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 ((Doc (Ann p) -> Doc (Ann p)) -> p -> p)
-> (Int -> Doc (Ann p) -> Doc (Ann p)) -> Int -> p -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Doc (Ann p) -> Doc (Ann p)
forall ann. Int -> Doc ann -> Doc ann
P.hang

-- | Indent lines in the argument to the current column + some delta.
indent :: Printer p => Int -> p -> p
indent :: Int -> p -> p
indent = (Doc (Ann p) -> Doc (Ann p)) -> p -> p
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 ((Doc (Ann p) -> Doc (Ann p)) -> p -> p)
-> (Int -> Doc (Ann p) -> Doc (Ann p)) -> Int -> p -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Doc (Ann p) -> Doc (Ann p)
forall ann. Int -> Doc ann -> Doc ann
P.indent


-- | @'nest' i p@ changes the indentation level for new lines in @p@ by @i@.
nest :: Printer p => Int -> p -> p
nest :: Int -> p -> p
nest = (Doc (Ann p) -> Doc (Ann p)) -> p -> p
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 ((Doc (Ann p) -> Doc (Ann p)) -> p -> p)
-> (Int -> Doc (Ann p) -> Doc (Ann p)) -> Int -> p -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Doc (Ann p) -> Doc (Ann p)
forall ann. Int -> Doc ann -> Doc ann
P.nest


concatWith :: (Monoid p, Foldable t) => (p -> p -> p) -> t p -> p
concatWith :: (p -> p -> p) -> t p -> p
concatWith p -> p -> p
(<>) t p
ds
  | t p -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null t p
ds   = p
forall a. Monoid a => a
mempty
  | Bool
otherwise = (p -> p -> p) -> t p -> p
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 p -> p -> p
(<>) t p
ds


hsep :: Printer p => [p] -> p
hsep :: [p] -> p
hsep = (p -> p -> p) -> [p] -> p
forall p (t :: * -> *).
(Monoid p, Foldable t) =>
(p -> p -> p) -> t p -> p
concatWith p -> p -> p
forall p. Printer p => p -> p -> p
(<+>)

vsep :: Printer p => [p] -> p
vsep :: [p] -> p
vsep = (p -> p -> p) -> [p] -> p
forall p (t :: * -> *).
(Monoid p, Foldable t) =>
(p -> p -> p) -> t p -> p
concatWith p -> p -> p
forall p. Printer p => p -> p -> p
(</>)

fillSep :: Printer p => [p] -> p
fillSep :: [p] -> p
fillSep = (p -> p -> p) -> [p] -> p
forall p (t :: * -> *).
(Monoid p, Foldable t) =>
(p -> p -> p) -> t p -> p
concatWith (p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
surround p
forall p. Printer p => p
softline)

sep :: Printer p => [p] -> p
sep :: [p] -> p
sep = p -> p
forall p. Printer p => p -> p
group (p -> p) -> ([p] -> p) -> [p] -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [p] -> p
forall p. Printer p => [p] -> p
vsep


hcat :: Printer p => [p] -> p
hcat :: [p] -> p
hcat = [p] -> p
forall a. Monoid a => [a] -> a
mconcat

vcat :: Printer p => [p] -> p
vcat :: [p] -> p
vcat = (p -> p -> p) -> [p] -> p
forall p (t :: * -> *).
(Monoid p, Foldable t) =>
(p -> p -> p) -> t p -> p
concatWith (p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
surround p
forall p. Printer p => p
line')

fillCat :: Printer p => [p] -> p
fillCat :: [p] -> p
fillCat = (p -> p -> p) -> [p] -> p
forall p (t :: * -> *).
(Monoid p, Foldable t) =>
(p -> p -> p) -> t p -> p
concatWith (p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
surround p
forall p. Printer p => p
softline')

cat :: Printer p => [p] -> p
cat :: [p] -> p
cat = p -> p
forall p. Printer p => p -> p
group (p -> p) -> ([p] -> p) -> [p] -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [p] -> p
forall p. Printer p => [p] -> p
vcat


punctuate :: Printer p => p -> [p] -> [p]
punctuate :: p -> [p] -> [p]
punctuate p
s = [p] -> [p]
go
  where
  go :: [p] -> [p]
go []     = []
  go [p
x]    = [p
x]
  go (p
x:[p]
xs) = p
x p -> p -> p
forall a. Semigroup a => a -> a -> a
<> p
s p -> [p] -> [p]
forall a. a -> [a] -> [a]
: [p] -> [p]
go [p]
xs


width :: Printer p => p -> (Int -> p) -> p
width :: p -> (Int -> p) -> p
width p
p Int -> p
f = (Int -> p) -> p
forall p. Printer p => (Int -> p) -> p
column ((Int -> p) -> p) -> (Int -> p) -> p
forall a b. (a -> b) -> a -> b
$ \ Int
start -> p
p p -> p -> p
forall a. Semigroup a => a -> a -> a
<> (Int -> p) -> p
forall p. Printer p => (Int -> p) -> p
column (\ Int
end -> Int -> p
f (Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
start))


fill :: Printer p => Int -> p -> p
fill :: Int -> p -> p
fill Int
n p
p = p -> (Int -> p) -> p
forall p. Printer p => p -> (Int -> p) -> p
width p
p ((Int -> p) -> p) -> (Int -> p) -> p
forall a b. (a -> b) -> a -> b
$ \ Int
w -> Int -> p -> p
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
w) p
forall p. Printer p => p
space

fillBreak :: Printer p => Int -> p -> p
fillBreak :: Int -> p -> p
fillBreak Int
f p
x = p -> (Int -> p) -> p
forall p. Printer p => p -> (Int -> p) -> p
width p
x Int -> p
go
  where
  go :: Int -> p
go Int
w
    | Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
f = Int -> p -> p
forall p. Printer p => Int -> p -> p
nest Int
f p
forall p. Printer p => p
line'
    | Bool
otherwise = Int -> p -> p
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes (Int
f Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
w) p
forall p. Printer p => p
space


-- | @'enclose' l r x@ wraps @x@ in @l@ and @r@.
enclose :: Printer p => p -> p -> p -> p
enclose :: p -> p -> p -> p
enclose p
l p
r p
x = p
l p -> p -> p
forall a. Semigroup a => a -> a -> a
<> p
x p -> p -> p
forall a. Semigroup a => a -> a -> a
<> p
r

encloseSep :: Printer p => p -> p -> p -> [p] -> p
encloseSep :: p -> p -> p -> [p] -> p
encloseSep p
l p
r p
s [p]
ps = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclose p
l p
r (p -> p
forall p. Printer p => p -> p
group ((p -> p -> p) -> [p] -> p
forall p (t :: * -> *).
(Monoid p, Foldable t) =>
(p -> p -> p) -> t p -> p
concatWith (p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
surround (p
forall p. Printer p => p
line' p -> p -> p
forall a. Semigroup a => a -> a -> a
<> p
s)) [p]
ps))

list :: Printer p => [p] -> p
list :: [p] -> p
list
  = p -> p
forall p. Printer p => p -> p
group
  (p -> p) -> ([p] -> p) -> [p] -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> p
forall p. Printer p => p -> p
brackets
  (p -> p) -> ([p] -> p) -> [p] -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> p -> p -> [p] -> p
forall p. Printer p => p -> p -> p -> [p] -> p
encloseSep
    (p -> p -> p
forall p. Printer p => p -> p -> p
flatAlt p
forall p. Printer p => p
space p
forall a. Monoid a => a
mempty)
    (p -> p -> p
forall p. Printer p => p -> p -> p
flatAlt p
forall p. Printer p => p
space p
forall a. Monoid a => a
mempty)
    (p
forall p. Printer p => p
comma p -> p -> p
forall a. Semigroup a => a -> a -> a
<> p
forall p. Printer p => p
space)

tupled :: Printer p => [p] -> p
tupled :: [p] -> p
tupled
  = p -> p
forall p. Printer p => p -> p
group
  (p -> p) -> ([p] -> p) -> [p] -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> p
forall p. Printer p => p -> p
parens
  (p -> p) -> ([p] -> p) -> [p] -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> p -> p -> [p] -> p
forall p. Printer p => p -> p -> p -> [p] -> p
encloseSep
    (p -> p -> p
forall p. Printer p => p -> p -> p
flatAlt p
forall p. Printer p => p
space p
forall a. Monoid a => a
mempty)
    (p -> p -> p
forall p. Printer p => p -> p -> p
flatAlt p
forall p. Printer p => p
space p
forall a. Monoid a => a
mempty)
    (p
forall p. Printer p => p
comma p -> p -> p
forall a. Semigroup a => a -> a -> a
<> p
forall p. Printer p => p
space)


-- | @'surround' x l r@ wraps @x@ in @l@ and @r@.
--
-- This is a reordering of 'enclose', but allows for convenient use in e.g. folds:
--
-- >>> 'foldr1' ('surround' ('pretty' ", ")) ['pretty' "apple", 'pretty' "banana"]
-- apple, banana
surround :: Printer p => p -> p -> p -> p
surround :: p -> p -> p -> p
surround p
x p
l p
r = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
enclose p
l p
r p
x

-- | Separate the arguments with a space.
(<+>) :: Printer p => p -> p -> p
<+> :: p -> p -> p
(<+>) = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
surround p
forall p. Printer p => p
space

infixr 6 <+>

-- | Separate the arguments with a line.
(</>) :: Printer p => p -> p -> p
</> :: p -> p -> p
(</>) = p -> p -> p -> p
forall p. Printer p => p -> p -> p -> p
surround p
forall p. Printer p => p
line

infixr 6 </>


-- | Conditional parenthesization of a printer. Analogous to 'showParen', but for printers.
parensIf :: Printer p => Bool -> p -> p
parensIf :: Bool -> p -> p
parensIf Bool
True = p -> p
forall p. Printer p => p -> p
parens
parensIf Bool
_    = p -> p
forall a. a -> a
id


-- Symbols

space :: Printer p => p
space :: p
space = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.space

line :: Printer p => p
line :: p
line = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.line

line' :: Printer p => p
line' :: p
line' = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.line'

softline :: Printer p => p
softline :: p
softline = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.softline

softline' :: Printer p => p
softline' :: p
softline' = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.softline'

hardline :: Printer p => p
hardline :: p
hardline = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.hardline

lparen, rparen :: Printer p => p
lparen :: p
lparen = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.lparen
rparen :: p
rparen = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.rparen

lbracket, rbracket :: Printer p => p
lbracket :: p
lbracket = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.lbracket
rbracket :: p
rbracket = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.rbracket

lbrace, rbrace :: Printer p => p
lbrace :: p
lbrace = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.lbrace
rbrace :: p
rbrace = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.rbrace

langle, rangle :: Printer p => p
langle :: p
langle = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.langle
rangle :: p
rangle = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.rangle

squote, dquote :: Printer p => p
squote :: p
squote = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.squote
dquote :: p
dquote = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.dquote

semi, comma, colon, dot, slash, backslash, equals, pipe :: Printer p => p
semi :: p
semi = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.semi
comma :: p
comma = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.comma
colon :: p
colon = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.colon
dot :: p
dot = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.dot
slash :: p
slash = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.slash
backslash :: p
backslash = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.backslash
equals :: p
equals = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.equals
pipe :: p
pipe = Doc (Ann p) -> p
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann p)
forall ann. Doc ann
P.pipe


instance Printer (P.Doc ann) where
  type Ann (P.Doc ann) = ann

  liftDoc0 :: Doc (Ann (Doc ann)) -> Doc ann
liftDoc0 = Doc (Ann (Doc ann)) -> Doc ann
forall a. a -> a
id
  liftDoc1 :: (Doc (Ann (Doc ann)) -> Doc (Ann (Doc ann))) -> Doc ann -> Doc ann
liftDoc1 = (Doc (Ann (Doc ann)) -> Doc (Ann (Doc ann))) -> Doc ann -> Doc ann
forall a. a -> a
id
  liftDoc2 :: (Doc (Ann (Doc ann)) -> Doc (Ann (Doc ann)) -> Doc (Ann (Doc ann)))
-> Doc ann -> Doc ann -> Doc ann
liftDoc2 = (Doc (Ann (Doc ann)) -> Doc (Ann (Doc ann)) -> Doc (Ann (Doc ann)))
-> Doc ann -> Doc ann -> Doc ann
forall a. a -> a
id

  enclosing :: Doc ann -> Doc ann -> Doc ann -> Doc ann
enclosing = Doc ann -> Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann -> Doc ann
P.enclose

  squotes :: Doc ann -> Doc ann
squotes = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
P.squotes
  dquotes :: Doc ann -> Doc ann
dquotes = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
P.dquotes
  parens :: Doc ann -> Doc ann
parens = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
P.parens
  brackets :: Doc ann -> Doc ann
brackets = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
P.brackets
  braces :: Doc ann -> Doc ann
braces = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
P.braces
  angles :: Doc ann -> Doc ann
angles = Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
P.angles

  column :: (Int -> Doc ann) -> Doc ann
column    = (Int -> Doc ann) -> Doc ann
forall ann. (Int -> Doc ann) -> Doc ann
P.column
  nesting :: (Int -> Doc ann) -> Doc ann
nesting   = (Int -> Doc ann) -> Doc ann
forall ann. (Int -> Doc ann) -> Doc ann
P.nesting
  pageWidth :: (PageWidth -> Doc ann) -> Doc ann
pageWidth = (PageWidth -> Doc ann) -> Doc ann
forall ann. (PageWidth -> Doc ann) -> Doc ann
P.pageWidth


instance (Printer a, Printer b, Ann a ~ Ann b) => Printer (a, b) where
  type Ann (a, b) = Ann b

  liftDoc0 :: Doc (Ann (a, b)) -> (a, b)
liftDoc0 Doc (Ann (a, b))
d = (Doc (Ann a) -> a
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann a)
Doc (Ann (a, b))
d, Doc (Ann b) -> b
forall p. Printer p => Doc (Ann p) -> p
liftDoc0 Doc (Ann b)
Doc (Ann (a, b))
d)
  liftDoc1 :: (Doc (Ann (a, b)) -> Doc (Ann (a, b))) -> (a, b) -> (a, b)
liftDoc1 Doc (Ann (a, b)) -> Doc (Ann (a, b))
f (a
a, b
b) = ((Doc (Ann a) -> Doc (Ann a)) -> a -> a
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 Doc (Ann a) -> Doc (Ann a)
Doc (Ann (a, b)) -> Doc (Ann (a, b))
f a
a, (Doc (Ann b) -> Doc (Ann b)) -> b -> b
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1 Doc (Ann b) -> Doc (Ann b)
Doc (Ann (a, b)) -> Doc (Ann (a, b))
f b
b)
  liftDoc2 :: (Doc (Ann (a, b)) -> Doc (Ann (a, b)) -> Doc (Ann (a, b)))
-> (a, b) -> (a, b) -> (a, b)
liftDoc2 Doc (Ann (a, b)) -> Doc (Ann (a, b)) -> Doc (Ann (a, b))
f (a
a1, b
b1) (a
a2, b
b2) = ((Doc (Ann a) -> Doc (Ann a) -> Doc (Ann a)) -> a -> a -> a
forall p.
Printer p =>
(Doc (Ann p) -> Doc (Ann p) -> Doc (Ann p)) -> p -> p -> p
liftDoc2 Doc (Ann a) -> Doc (Ann a) -> Doc (Ann a)
Doc (Ann (a, b)) -> Doc (Ann (a, b)) -> Doc (Ann (a, b))
f a
a1 a
a2, (Doc (Ann b) -> Doc (Ann b) -> Doc (Ann b)) -> b -> b -> b
forall p.
Printer p =>
(Doc (Ann p) -> Doc (Ann p) -> Doc (Ann p)) -> p -> p -> p
liftDoc2 Doc (Ann b) -> Doc (Ann b) -> Doc (Ann b)
Doc (Ann (a, b)) -> Doc (Ann (a, b)) -> Doc (Ann (a, b))
f b
b1 b
b2)

  enclosing :: (a, b) -> (a, b) -> (a, b) -> (a, b)
enclosing (a
l1, b
l2) (a
r1, b
r2) (a
x1, b
x2) = (a -> a -> a -> a
forall p. Printer p => p -> p -> p -> p
enclosing a
l1 a
r1 a
x1, b -> b -> b -> b
forall p. Printer p => p -> p -> p -> p
enclosing b
l2 b
r2 b
x2)

  squotes :: (a, b) -> (a, b)
squotes (a
a, b
b) = (a -> a
forall p. Printer p => p -> p
squotes a
a, b -> b
forall p. Printer p => p -> p
squotes b
b)
  dquotes :: (a, b) -> (a, b)
dquotes (a
a, b
b) = (a -> a
forall p. Printer p => p -> p
dquotes a
a, b -> b
forall p. Printer p => p -> p
dquotes b
b)
  parens :: (a, b) -> (a, b)
parens (a
a, b
b) = (a -> a
forall p. Printer p => p -> p
parens a
a, b -> b
forall p. Printer p => p -> p
parens b
b)
  brackets :: (a, b) -> (a, b)
brackets (a
a, b
b) = (a -> a
forall p. Printer p => p -> p
brackets a
a, b -> b
forall p. Printer p => p -> p
brackets b
b)
  braces :: (a, b) -> (a, b)
braces (a
a, b
b) = (a -> a
forall p. Printer p => p -> p
braces a
a, b -> b
forall p. Printer p => p -> p
braces b
b)
  angles :: (a, b) -> (a, b)
angles (a
a, b
b) = (a -> a
forall p. Printer p => p -> p
angles a
a, b -> b
forall p. Printer p => p -> p
angles b
b)

  column :: (Int -> (a, b)) -> (a, b)
column    Int -> (a, b)
f = ((Int -> a) -> a
forall p. Printer p => (Int -> p) -> p
column    ((a, b) -> a
forall a b. (a, b) -> a
fst ((a, b) -> a) -> (Int -> (a, b)) -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (a, b)
f), (Int -> b) -> b
forall p. Printer p => (Int -> p) -> p
column    ((a, b) -> b
forall a b. (a, b) -> b
snd ((a, b) -> b) -> (Int -> (a, b)) -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (a, b)
f))
  nesting :: (Int -> (a, b)) -> (a, b)
nesting   Int -> (a, b)
f = ((Int -> a) -> a
forall p. Printer p => (Int -> p) -> p
nesting   ((a, b) -> a
forall a b. (a, b) -> a
fst ((a, b) -> a) -> (Int -> (a, b)) -> Int -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (a, b)
f), (Int -> b) -> b
forall p. Printer p => (Int -> p) -> p
nesting   ((a, b) -> b
forall a b. (a, b) -> b
snd ((a, b) -> b) -> (Int -> (a, b)) -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (a, b)
f))
  pageWidth :: (PageWidth -> (a, b)) -> (a, b)
pageWidth PageWidth -> (a, b)
f = ((PageWidth -> a) -> a
forall p. Printer p => (PageWidth -> p) -> p
pageWidth ((a, b) -> a
forall a b. (a, b) -> a
fst ((a, b) -> a) -> (PageWidth -> (a, b)) -> PageWidth -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PageWidth -> (a, b)
f), (PageWidth -> b) -> b
forall p. Printer p => (PageWidth -> p) -> p
pageWidth ((a, b) -> b
forall a b. (a, b) -> b
snd ((a, b) -> b) -> (PageWidth -> (a, b)) -> PageWidth -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PageWidth -> (a, b)
f))


instance Printer b => Printer (a -> b) where
  type Ann (a -> b) = Ann b

  liftDoc0 :: Doc (Ann (a -> b)) -> a -> b
liftDoc0 = b -> a -> b
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> a -> b) -> (Doc (Ann b) -> b) -> Doc (Ann b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc (Ann b) -> b
forall p. Printer p => Doc (Ann p) -> p
liftDoc0
  liftDoc1 :: (Doc (Ann (a -> b)) -> Doc (Ann (a -> b))) -> (a -> b) -> a -> b
liftDoc1 = (b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((b -> b) -> (a -> b) -> a -> b)
-> ((Doc (Ann b) -> Doc (Ann b)) -> b -> b)
-> (Doc (Ann b) -> Doc (Ann b))
-> (a -> b)
-> a
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Doc (Ann b) -> Doc (Ann b)) -> b -> b
forall p. Printer p => (Doc (Ann p) -> Doc (Ann p)) -> p -> p
liftDoc1
  liftDoc2 :: (Doc (Ann (a -> b)) -> Doc (Ann (a -> b)) -> Doc (Ann (a -> b)))
-> (a -> b) -> (a -> b) -> a -> b
liftDoc2 = (b -> b -> b) -> (a -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 ((b -> b -> b) -> (a -> b) -> (a -> b) -> a -> b)
-> ((Doc (Ann b) -> Doc (Ann b) -> Doc (Ann b)) -> b -> b -> b)
-> (Doc (Ann b) -> Doc (Ann b) -> Doc (Ann b))
-> (a -> b)
-> (a -> b)
-> a
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Doc (Ann b) -> Doc (Ann b) -> Doc (Ann b)) -> b -> b -> b
forall p.
Printer p =>
(Doc (Ann p) -> Doc (Ann p) -> Doc (Ann p)) -> p -> p -> p
liftDoc2

  enclosing :: (a -> b) -> (a -> b) -> (a -> b) -> a -> b
enclosing a -> b
l a -> b
r a -> b
x = b -> b -> b -> b
forall p. Printer p => p -> p -> p -> p
enclosing (b -> b -> b -> b) -> (a -> b) -> a -> b -> b -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> b
l (a -> b -> b -> b) -> (a -> b) -> a -> b -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> b
r (a -> b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> b
x

  squotes :: (a -> b) -> a -> b
squotes = (b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall p. Printer p => p -> p
squotes
  dquotes :: (a -> b) -> a -> b
dquotes = (b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall p. Printer p => p -> p
dquotes
  parens :: (a -> b) -> a -> b
parens = (b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall p. Printer p => p -> p
parens
  brackets :: (a -> b) -> a -> b
brackets = (b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall p. Printer p => p -> p
brackets
  braces :: (a -> b) -> a -> b
braces = (b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall p. Printer p => p -> p
braces
  angles :: (a -> b) -> a -> b
angles = (b -> b) -> (a -> b) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall p. Printer p => p -> p
angles

  column :: (Int -> a -> b) -> a -> b
column    Int -> a -> b
f = (Int -> b) -> b
forall p. Printer p => (Int -> p) -> p
column    ((Int -> b) -> b) -> (a -> Int -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> b) -> a -> Int -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> a -> b
f
  nesting :: (Int -> a -> b) -> a -> b
nesting   Int -> a -> b
f = (Int -> b) -> b
forall p. Printer p => (Int -> p) -> p
nesting   ((Int -> b) -> b) -> (a -> Int -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> a -> b) -> a -> Int -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> a -> b
f
  pageWidth :: (PageWidth -> a -> b) -> a -> b
pageWidth PageWidth -> a -> b
f = (PageWidth -> b) -> b
forall p. Printer p => (PageWidth -> p) -> p
pageWidth ((PageWidth -> b) -> b) -> (a -> PageWidth -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PageWidth -> a -> b) -> a -> PageWidth -> b
forall a b c. (a -> b -> c) -> b -> a -> c
flip PageWidth -> a -> b
f