    -- | __Warning: internal module!__ This means that the API may change
    -- arbitrarily between versions without notice. Depending on this module may
    -- lead to unexpected breakages, so proceed with caution!
    --
    -- This module provides debugging helpers for inspecting 'Doc's.
    --
    -- Use the @pretty-simple@ package to get a nicer layout for 'show'n
    -- 'Diag's:
    --
    -- > > Text.Pretty.Simple.pPrintNoColor . diag $ align (vcat ["foo", "bar"])
    -- > Column
    -- >    [
    -- >        ( 10
    -- >        , Nesting
    -- >            [
    -- >                ( 10
    -- >                , Cat ( Text 3 "foo" )
    -- >                    ( Cat ( FlatAlt Line Empty ) ( Text 3 "bar" ) )
    -- >                )
    -- >            ]
    -- >        )
    -- >    ]

    module Data.Text.Prettyprint.Doc.Internal.Debug where

    import Data.Text (Text)
    import Data.Text.Prettyprint.Doc.Internal (PageWidth, Doc)
    import qualified Data.Text.Prettyprint.Doc.Internal as Doc

    -- | A variant of 'Doc' for debugging.
    --
    -- Unlike in the 'Doc' type, the 'Column', 'WithPageWidth' and 'Nesting'
    -- constructors don't contain functions but are \"sampled\" to allow
    -- simple inspection with 'show'.
    data Diag ann =
        Fail
        | Empty
        | Char !Char
        | Text !Int !Text
        | Line
        | FlatAlt (Diag ann) (Diag ann)
        | Cat (Diag ann) (Diag ann)
        | Nest !Int (Diag ann)
        | Union (Diag ann) (Diag ann)
        | Column [(Int, Diag ann)]
          -- ^ 'Doc': @(Int -> Diag ann)@
        | WithPageWidth [(PageWidth, Diag ann)]
          -- ^ 'Doc': @(PageWidth -> Diag ann)@
        | Nesting [(Int, Diag ann)]
          -- ^ 'Doc': @(Int -> Diag ann)@
        | Annotated ann (Diag ann)
        deriving Int -> Diag ann -> ShowS
    [Diag ann] -> ShowS
    Diag ann -> String
    (Int -> Diag ann -> ShowS)
    -> (Diag ann -> String) -> ([Diag ann] -> ShowS) -> Show (Diag ann)
    forall ann. Show ann => Int -> Diag ann -> ShowS
    forall ann. Show ann => [Diag ann] -> ShowS
    forall ann. Show ann => Diag ann -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Diag ann] -> ShowS
    $cshowList :: forall ann. Show ann => [Diag ann] -> ShowS
    show :: Diag ann -> String
    $cshow :: forall ann. Show ann => Diag ann -> String
    showsPrec :: Int -> Diag ann -> ShowS
    $cshowsPrec :: forall ann. Show ann => Int -> Diag ann -> ShowS
    Show

    -- | Convert a 'Doc' to its diagnostic representation.
    --
    -- The functions in the 'Column', 'WithPageWidth' and 'Nesting' constructors are
    -- sampled with some default values.
    --
    -- Use `diag'` to control the function inputs yourself.
    --
    -- >>> diag $ Doc.align (Doc.vcat ["foo", "bar"])
    -- Column [(10,Nesting [(10,Cat (Text 3 "foo") (Cat (FlatAlt Line Empty) (Text 3 "bar")))])]
    diag :: Doc ann -> Diag ann
    diag :: Doc ann -> Diag ann
    diag = [Int] -> [PageWidth] -> [Int] -> Doc ann -> Diag ann
    forall ann. [Int] -> [PageWidth] -> [Int] -> Doc ann -> Diag ann
    diag' [10] [PageWidth
    Doc.defaultPageWidth] [10]

    diag'
        :: [Int]
           -- ^ Cursor positions for the 'Column' constructor
        -> [PageWidth]
           -- ^ For 'WithPageWidth'
        -> [Int]
           -- ^ Nesting levels for 'Nesting'
        -> Doc ann
        -> Diag ann
    diag' :: [Int] -> [PageWidth] -> [Int] -> Doc ann -> Diag ann
    diag' columns :: [Int]
    columns pageWidths :: [PageWidth]
    pageWidths nestings :: [Int]
    nestings = Doc ann -> Diag ann
    forall ann. Doc ann -> Diag ann
    go
      where
        go :: Doc ann -> Diag ann
    go doc :: Doc ann
    doc = case Doc ann
    doc of
            Doc.Fail -> Diag ann
    forall ann. Diag ann
    Fail
            Doc.Empty -> Diag ann
    forall ann. Diag ann
    Empty
            Doc.Char c :: Char
    c -> Char -> Diag ann
    forall ann. Char -> Diag ann
    Char Char
    c
            Doc.Text l :: Int
    l t :: Text
    t -> Int -> Text -> Diag ann
    forall ann. Int -> Text -> Diag ann
    Text Int
    l Text
    t
            Doc.Line -> Diag ann
    forall ann. Diag ann
    Line
            Doc.FlatAlt a :: Doc ann
    a b :: Doc ann
    b -> Diag ann -> Diag ann -> Diag ann
    forall ann. Diag ann -> Diag ann -> Diag ann
    FlatAlt (Doc ann -> Diag ann
    go Doc ann
    a) (Doc ann -> Diag ann
    go Doc ann
    b)
            Doc.Cat a :: Doc ann
    a b :: Doc ann
    b -> Diag ann -> Diag ann -> Diag ann
    forall ann. Diag ann -> Diag ann -> Diag ann
    Cat (Doc ann -> Diag ann
    go Doc ann
    a) (Doc ann -> Diag ann
    go Doc ann
    b)
            Doc.Nest i :: Int
    i d :: Doc ann
    d -> Int -> Diag ann -> Diag ann
    forall ann. Int -> Diag ann -> Diag ann
    Nest Int
    i (Doc ann -> Diag ann
    go Doc ann
    d)
            Doc.Union a :: Doc ann
    a b :: Doc ann
    b -> Diag ann -> Diag ann -> Diag ann
    forall ann. Diag ann -> Diag ann -> Diag ann
    Union (Doc ann -> Diag ann
    go Doc ann
    a) (Doc ann -> Diag ann
    go Doc ann
    b)
            Doc.Column f :: Int -> Doc ann
    f -> [(Int, Diag ann)] -> Diag ann
    forall ann. [(Int, Diag ann)] -> Diag ann
    Column ((Int -> Doc ann) -> [Int] -> [(Int, Diag ann)]
    forall a ann. (a -> Doc ann) -> [a] -> [(a, Diag ann)]
    apply Int -> Doc ann
    f [Int]
    columns)
            Doc.WithPageWidth f :: PageWidth -> Doc ann
    f -> [(PageWidth, Diag ann)] -> Diag ann
    forall ann. [(PageWidth, Diag ann)] -> Diag ann
    WithPageWidth ((PageWidth -> Doc ann) -> [PageWidth] -> [(PageWidth, Diag ann)]
    forall a ann. (a -> Doc ann) -> [a] -> [(a, Diag ann)]
    apply PageWidth -> Doc ann
    f [PageWidth]
    pageWidths)
            Doc.Nesting f :: Int -> Doc ann
    f -> [(Int, Diag ann)] -> Diag ann
    forall ann. [(Int, Diag ann)] -> Diag ann
    Nesting ((Int -> Doc ann) -> [Int] -> [(Int, Diag ann)]
    forall a ann. (a -> Doc ann) -> [a] -> [(a, Diag ann)]
    apply Int -> Doc ann
    f [Int]
    nestings)
            Doc.Annotated ann :: ann
    ann d :: Doc ann
    d -> ann -> Diag ann -> Diag ann
    forall ann. ann -> Diag ann -> Diag ann
    Annotated ann
    ann (Doc ann -> Diag ann
    go Doc ann
    d)

        apply :: (a -> Doc ann) -> [a] -> [(a, Diag ann)]
        apply :: (a -> Doc ann) -> [a] -> [(a, Diag ann)]
    apply f :: a -> Doc ann
    f = (a -> (a, Diag ann)) -> [a] -> [(a, Diag ann)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\x :: a
    x -> (a
    x, Doc ann -> Diag ann
    forall ann. Doc ann -> Diag ann
    go (a -> Doc ann
    f a
    x)))