Sophie

Sophie

distrib > Fedora > 14 > i386 > by-pkgid > 8d1ef08c9e0d44c69764afc615a03d0d > files > 1817

ghc-ghc-devel-6.12.3-5.fc14.i686.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ -->
<title>utils/Pretty.lhs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
%*********************************************************************************
%*                                                                               *
%*       John Hughes's and Simon Peyton Jones's Pretty Printer Combinators       *
%*                                                                               *
%*               based on "The Design of a Pretty-printing Library"              *
%*               in Advanced Functional Programming,                             *
%*               Johan Jeuring and Erik Meijer (eds), LNCS 925                   *
%*               http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps                *
%*                                                                               *
%*               Heavily modified by Simon Peyton Jones, Dec 96                  *
%*                                                                               *
%*********************************************************************************

Version 3.0     28 May 1997
  * Cured massive performance bug.  If you write

        foldl <> empty (map (text.show) [1..10000])

    you get quadratic behaviour with V2.0.  Why?  For just the same reason as you get
    quadratic behaviour with left-associated (++) chains.

    This is really bad news.  One thing a pretty-printer abstraction should
    certainly guarantee is insensivity to associativity.  It matters: suddenly
    GHC's compilation times went up by a factor of 100 when I switched to the
    new pretty printer.

    I fixed it with a bit of a hack (because I wanted to get GHC back on the
    road).  I added two new constructors to the Doc type, Above and Beside:

         <> = Beside
         $$ = Above

    Then, where I need to get to a "TextBeside" or "NilAbove" form I "force"
    the Doc to squeeze out these suspended calls to Beside and Above; but in so
    doing I re-associate. It's quite simple, but I'm not satisfied that I've done
    the best possible job.  I'll send you the code if you are interested.

  * Added new exports:
        punctuate, hang
        int, integer, float, double, rational,
        lparen, rparen, lbrack, rbrack, lbrace, rbrace,

  * fullRender's type signature has changed.  Rather than producing a string it
    now takes an extra couple of arguments that tells it how to glue fragments
    of output together:

        fullRender :: Mode
                   -> Int                       -- Line length
                   -> Float                     -- Ribbons per line
                   -> (TextDetails -> a -> a)   -- What to do with text
                   -> a                         -- What to do at the end
                   -> Doc
                   -> a                         -- Result

    The "fragments" are encapsulated in the TextDetails data type:
        data TextDetails = Chr  Char
                         | Str  String
                         | PStr FastString

    The Chr and Str constructors are obvious enough.  The PStr constructor has a packed
    string (FastString) inside it.  It's generated by using the new "ptext" export.

    An advantage of this new setup is that you can get the renderer to do output
    directly (by passing in a function of type (TextDetails -> IO () -> IO ()),
    rather than producing a string that you then print.


Version 2.0     24 April 1997
  * Made empty into a left unit for <> as well as a right unit;
    it is also now true that
        nest k empty = empty
    which wasn't true before.

  * Fixed an obscure bug in sep that occassionally gave very wierd behaviour

  * Added $+$

  * Corrected and tidied up the laws and invariants

======================================================================
Relative to John's original paper, there are the following new features:

1.  There's an empty document, "empty".  It's a left and right unit for
    both <> and $$, and anywhere in the argument list for
    sep, hcat, hsep, vcat, fcat etc.

    It is Really Useful in practice.

2.  There is a paragraph-fill combinator, fsep, that's much like sep,
    only it keeps fitting things on one line until it can't fit any more.

3.  Some random useful extra combinators are provided.
        <+> puts its arguments beside each other with a space between them,
            unless either argument is empty in which case it returns the other


        hcat is a list version of <>
        hsep is a list version of <+>
        vcat is a list version of $$

        sep (separate) is either like hsep or like vcat, depending on what fits

        cat  is behaves like sep,  but it uses <> for horizontal conposition
        fcat is behaves like fsep, but it uses <> for horizontal conposition

        These new ones do the obvious things:
                char, semi, comma, colon, space,
                parens, brackets, braces,
                quotes, doubleQuotes

4.      The "above" combinator, $$, now overlaps its two arguments if the
        last line of the top argument stops before the first line of the second begins.
        For example:  text "hi" $$ nest 5 "there"
        lays out as
                        hi   there
        rather than
                        hi
                             there

        There are two places this is really useful

        a) When making labelled blocks, like this:
                Left ->   code for left
                Right ->  code for right
                LongLongLongLabel ->
                          code for longlonglonglabel
           The block is on the same line as the label if the label is
           short, but on the next line otherwise.

        b) When laying out lists like this:
                [ first
                , second
                , third
                ]
           which some people like.  But if the list fits on one line
           you want [first, second, third].  You can't do this with
           John's original combinators, but it's quite easy with the
           new $$.

        The combinator $+$ gives the original "never-overlap" behaviour.

5.      Several different renderers are provided:
                * a standard one
                * one that uses cut-marks to avoid deeply-nested documents
                        simply piling up in the right-hand margin
                * one that ignores indentation (fewer chars output; good for machines)
                * one that ignores indentation and newlines (ditto, only more so)

6.      Numerous implementation tidy-ups
        Use of unboxed data types to speed up the implementation



\begin{code}
<pre><a name="line-1"></a><span class='hs-comment'>{-# OPTIONS -fno-warn-unused-imports #-}</span>
<a name="line-2"></a><span class='hs-comment'>-- XXX GHC 6.9 seems to be confused by unpackCString# being used only in</span>
<a name="line-3"></a><span class='hs-comment'>--     a RULE</span>
<a name="line-4"></a>
<a name="line-5"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Pretty</span> <span class='hs-layout'>(</span>
<a name="line-6"></a>        <span class='hs-conid'>Doc</span><span class='hs-layout'>,</span>            <span class='hs-comment'>-- Abstract</span>
<a name="line-7"></a>        <span class='hs-conid'>Mode</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>TextDetails</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-8"></a>
<a name="line-9"></a>        <span class='hs-varid'>empty</span><span class='hs-layout'>,</span> <span class='hs-varid'>isEmpty</span><span class='hs-layout'>,</span> <span class='hs-varid'>nest</span><span class='hs-layout'>,</span>
<a name="line-10"></a>
<a name="line-11"></a>        <span class='hs-varid'>char</span><span class='hs-layout'>,</span> <span class='hs-varid'>text</span><span class='hs-layout'>,</span> <span class='hs-varid'>ftext</span><span class='hs-layout'>,</span> <span class='hs-varid'>ptext</span><span class='hs-layout'>,</span>
<a name="line-12"></a>        <span class='hs-varid'>int</span><span class='hs-layout'>,</span> <span class='hs-varid'>integer</span><span class='hs-layout'>,</span> <span class='hs-varid'>float</span><span class='hs-layout'>,</span> <span class='hs-varid'>double</span><span class='hs-layout'>,</span> <span class='hs-varid'>rational</span><span class='hs-layout'>,</span>
<a name="line-13"></a>        <span class='hs-varid'>parens</span><span class='hs-layout'>,</span> <span class='hs-varid'>brackets</span><span class='hs-layout'>,</span> <span class='hs-varid'>braces</span><span class='hs-layout'>,</span> <span class='hs-varid'>quotes</span><span class='hs-layout'>,</span> <span class='hs-varid'>doubleQuotes</span><span class='hs-layout'>,</span>
<a name="line-14"></a>        <span class='hs-varid'>semi</span><span class='hs-layout'>,</span> <span class='hs-varid'>comma</span><span class='hs-layout'>,</span> <span class='hs-varid'>colon</span><span class='hs-layout'>,</span> <span class='hs-varid'>space</span><span class='hs-layout'>,</span> <span class='hs-varid'>equals</span><span class='hs-layout'>,</span>
<a name="line-15"></a>        <span class='hs-varid'>lparen</span><span class='hs-layout'>,</span> <span class='hs-varid'>rparen</span><span class='hs-layout'>,</span> <span class='hs-varid'>lbrack</span><span class='hs-layout'>,</span> <span class='hs-varid'>rbrack</span><span class='hs-layout'>,</span> <span class='hs-varid'>lbrace</span><span class='hs-layout'>,</span> <span class='hs-varid'>rbrace</span><span class='hs-layout'>,</span> <span class='hs-varid'>cparen</span><span class='hs-layout'>,</span>
<a name="line-16"></a>
<a name="line-17"></a>        <span class='hs-layout'>(</span><span class='hs-varop'>&lt;&gt;</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>&lt;+&gt;</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>hcat</span><span class='hs-layout'>,</span> <span class='hs-varid'>hsep</span><span class='hs-layout'>,</span>
<a name="line-18"></a>        <span class='hs-layout'>(</span><span class='hs-varop'>$$</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varop'>$+$</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>vcat</span><span class='hs-layout'>,</span>
<a name="line-19"></a>        <span class='hs-varid'>sep</span><span class='hs-layout'>,</span> <span class='hs-varid'>cat</span><span class='hs-layout'>,</span>
<a name="line-20"></a>        <span class='hs-varid'>fsep</span><span class='hs-layout'>,</span> <span class='hs-varid'>fcat</span><span class='hs-layout'>,</span>
<a name="line-21"></a>
<a name="line-22"></a>        <span class='hs-varid'>hang</span><span class='hs-layout'>,</span> <span class='hs-varid'>punctuate</span><span class='hs-layout'>,</span>
<a name="line-23"></a>
<a name="line-24"></a><span class='hs-comment'>--      renderStyle,            -- Haskell 1.3 only</span>
<a name="line-25"></a>        <span class='hs-varid'>render</span><span class='hs-layout'>,</span> <span class='hs-varid'>fullRender</span><span class='hs-layout'>,</span> <span class='hs-varid'>printDoc</span><span class='hs-layout'>,</span> <span class='hs-varid'>showDocWith</span><span class='hs-layout'>,</span>
<a name="line-26"></a>        <span class='hs-varid'>bufLeftRender</span> <span class='hs-comment'>-- performance hack</span>
<a name="line-27"></a>  <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-28"></a>
<a name="line-29"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>BufWrite</span>
<a name="line-30"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>FastString</span>
<a name="line-31"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>FastTypes</span>
<a name="line-32"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Panic</span>
<a name="line-33"></a>
<a name="line-34"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Numeric</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromRat</span><span class='hs-layout'>)</span>
<a name="line-35"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>IO</span>
<a name="line-36"></a><span class='hs-comment'>--import Foreign.Ptr (castPtr)</span>
<a name="line-37"></a>
<a name="line-38"></a><span class='hs-cpp'>#if defined(__GLASGOW_HASKELL__)</span>
<a name="line-39"></a><span class='hs-comment'>--for a RULES</span>
<a name="line-40"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Base</span> <span class='hs-layout'>(</span> <span class='hs-varid'>unpackCString</span><span class='hs-cpp'>#</span> <span class='hs-layout'>)</span>
<a name="line-41"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Exts</span> <span class='hs-layout'>(</span> <span class='hs-conid'>Int</span><span class='hs-cpp'>#</span> <span class='hs-layout'>)</span>
<a name="line-42"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>GHC</span><span class='hs-varop'>.</span><span class='hs-conid'>Ptr</span>  <span class='hs-layout'>(</span> <span class='hs-conid'>Ptr</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span> <span class='hs-layout'>)</span>
<a name="line-43"></a><span class='hs-cpp'>#endif</span>
<a name="line-44"></a>
<a name="line-45"></a><span class='hs-comment'>-- Don't import Util( assertPanic ) because it makes a loop in the module structure</span>
<a name="line-46"></a>
<a name="line-47"></a><span class='hs-keyword'>infixl</span> <span class='hs-num'>6</span> <span class='hs-varop'>&lt;&gt;</span>
<a name="line-48"></a><span class='hs-keyword'>infixl</span> <span class='hs-num'>6</span> <span class='hs-varop'>&lt;+&gt;</span>
<a name="line-49"></a><span class='hs-keyword'>infixl</span> <span class='hs-num'>5</span> <span class='hs-varop'>$$</span><span class='hs-layout'>,</span> <span class='hs-varop'>$+$</span>
</pre>\end{code}


\begin{code}
<pre><a name="line-1"></a>
<a name="line-2"></a><span class='hs-comment'>-- Disable ASSERT checks; they are expensive!</span>
<a name="line-3"></a><span class='hs-cpp'>#define LOCAL_ASSERT(x)</span>
<a name="line-4"></a>
</pre>\end{code}


%*********************************************************
%*                                                       *
\subsection{The interface}
%*                                                       *
%*********************************************************

The primitive @Doc@ values

\begin{code}
<pre><a name="line-1"></a><a name="empty"></a><span class='hs-definition'>empty</span>                     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span>
<a name="line-2"></a><a name="isEmpty"></a><span class='hs-definition'>isEmpty</span>                   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-3"></a><a name="text"></a><span class='hs-definition'>text</span>                      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-4"></a><a name="char"></a><span class='hs-definition'>char</span>                      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Char</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-5"></a>
<a name="line-6"></a><a name="semi"></a><span class='hs-definition'>semi</span><span class='hs-layout'>,</span> <span class='hs-varid'>comma</span><span class='hs-layout'>,</span> <span class='hs-varid'>colon</span><span class='hs-layout'>,</span> <span class='hs-varid'>space</span><span class='hs-layout'>,</span> <span class='hs-varid'>equals</span>              <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span>
<a name="line-7"></a><a name="lparen"></a><span class='hs-definition'>lparen</span><span class='hs-layout'>,</span> <span class='hs-varid'>rparen</span><span class='hs-layout'>,</span> <span class='hs-varid'>lbrack</span><span class='hs-layout'>,</span> <span class='hs-varid'>rbrack</span><span class='hs-layout'>,</span> <span class='hs-varid'>lbrace</span><span class='hs-layout'>,</span> <span class='hs-varid'>rbrace</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span>
<a name="line-8"></a>
<a name="line-9"></a><a name="parens"></a><span class='hs-definition'>parens</span><span class='hs-layout'>,</span> <span class='hs-varid'>brackets</span><span class='hs-layout'>,</span> <span class='hs-varid'>braces</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-10"></a><a name="quotes"></a><span class='hs-definition'>quotes</span><span class='hs-layout'>,</span> <span class='hs-varid'>doubleQuotes</span>      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-11"></a>
<a name="line-12"></a><a name="int"></a><span class='hs-definition'>int</span>      <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-13"></a><a name="integer"></a><span class='hs-definition'>integer</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-14"></a><a name="float"></a><span class='hs-definition'>float</span>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Float</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-15"></a><a name="double"></a><span class='hs-definition'>double</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Double</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-16"></a><a name="rational"></a><span class='hs-definition'>rational</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Rational</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
</pre>\end{code}

Combining @Doc@ values

\begin{code}
<pre><a name="line-1"></a><a name="<>"></a><span class='hs-layout'>(</span><span class='hs-varop'>&lt;&gt;</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>     <span class='hs-comment'>-- Beside</span>
<a name="line-2"></a><a name="hcat"></a><span class='hs-definition'>hcat</span>   <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>          <span class='hs-comment'>-- List version of &lt;&gt;</span>
<a name="line-3"></a><a name="<+>"></a><span class='hs-layout'>(</span><span class='hs-varop'>&lt;+&gt;</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>     <span class='hs-comment'>-- Beside, separated by space</span>
<a name="line-4"></a><a name="hsep"></a><span class='hs-definition'>hsep</span>   <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>          <span class='hs-comment'>-- List version of &lt;+&gt;</span>
<a name="line-5"></a>
<a name="line-6"></a><a name="$$"></a><span class='hs-layout'>(</span><span class='hs-varop'>$$</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>     <span class='hs-comment'>-- Above; if there is no</span>
<a name="line-7"></a>                                <span class='hs-comment'>-- overlap it "dovetails" the two</span>
<a name="line-8"></a><a name="vcat"></a><span class='hs-definition'>vcat</span>   <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>          <span class='hs-comment'>-- List version of $$</span>
<a name="line-9"></a>
<a name="line-10"></a><a name="cat"></a><span class='hs-definition'>cat</span>    <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>          <span class='hs-comment'>-- Either hcat or vcat</span>
<a name="line-11"></a><a name="sep"></a><span class='hs-definition'>sep</span>    <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>          <span class='hs-comment'>-- Either hsep or vcat</span>
<a name="line-12"></a><a name="fcat"></a><span class='hs-definition'>fcat</span>   <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>          <span class='hs-comment'>-- ``Paragraph fill'' version of cat</span>
<a name="line-13"></a><a name="fsep"></a><span class='hs-definition'>fsep</span>   <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>          <span class='hs-comment'>-- ``Paragraph fill'' version of sep</span>
<a name="line-14"></a>
<a name="line-15"></a><a name="nest"></a><span class='hs-definition'>nest</span>   <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>     <span class='hs-comment'>-- Nested</span>
</pre>\end{code}

GHC-specific ones.

\begin{code}
<pre><a name="line-1"></a><a name="hang"></a><span class='hs-definition'>hang</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-2"></a><a name="punctuate"></a><span class='hs-definition'>punctuate</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span>      <span class='hs-comment'>-- punctuate p [d1, ... dn] = [d1 &lt;&gt; p, d2 &lt;&gt; p, ... dn-1 &lt;&gt; p, dn]</span>
</pre>\end{code}

Displaying @Doc@ values.

\begin{code}
<pre><a name="line-1"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Show</span> <span class='hs-conid'>Doc</span> <span class='hs-keyword'>where</span>
<a name="line-2"></a>  <span class='hs-varid'>showsPrec</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>doc</span> <span class='hs-varid'>cont</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>showDoc</span> <span class='hs-varid'>doc</span> <span class='hs-varid'>cont</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="render"></a><span class='hs-definition'>render</span>     <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>             <span class='hs-comment'>-- Uses default style</span>
<a name="line-5"></a><a name="fullRender"></a><span class='hs-definition'>fullRender</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Mode</span>
<a name="line-6"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>                       <span class='hs-comment'>-- Line length</span>
<a name="line-7"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Float</span>                     <span class='hs-comment'>-- Ribbons per line</span>
<a name="line-8"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextDetails</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>   <span class='hs-comment'>-- What to do with text</span>
<a name="line-9"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>                         <span class='hs-comment'>-- What to do at the end</span>
<a name="line-10"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-11"></a>           <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>                         <span class='hs-comment'>-- Result</span>
<a name="line-12"></a>
<a name="line-13"></a><span class='hs-comment'>{-      When we start using 1.3
<a name="line-14"></a>renderStyle  :: Style -&gt; Doc -&gt; String
<a name="line-15"></a>data Style = Style { lineLength     :: Int,     -- In chars
<a name="line-16"></a>                     ribbonsPerLine :: Float,   -- Ratio of ribbon length to line length
<a name="line-17"></a>                     mode :: Mode
<a name="line-18"></a>             }
<a name="line-19"></a>style :: Style          -- The default style
<a name="line-20"></a>style = Style { lineLength = 100, ribbonsPerLine = 2.5, mode = PageMode }
<a name="line-21"></a>-}</span>
<a name="line-22"></a>
<a name="line-23"></a><a name="Mode"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Mode</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>PageMode</span>            <span class='hs-comment'>-- Normal</span>
<a name="line-24"></a>          <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ZigZagMode</span>          <span class='hs-comment'>-- With zig-zag cuts</span>
<a name="line-25"></a>          <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LeftMode</span>            <span class='hs-comment'>-- No indentation, infinitely long lines</span>
<a name="line-26"></a>          <span class='hs-keyglyph'>|</span> <span class='hs-conid'>OneLineMode</span>         <span class='hs-comment'>-- All on one line</span>
<a name="line-27"></a>
</pre>\end{code}


%*********************************************************
%*                                                       *
\subsection{The @Doc@ calculus}
%*                                                       *
%*********************************************************

The @Doc@ combinators satisfy the following laws:
\begin{verbatim}
Laws for $$
~~~~~~~~~~~
<a1>    (x $$ y) $$ z   = x $$ (y $$ z)
<a2>    empty $$ x      = x
<a3>    x $$ empty      = x

        ...ditto $+$...

Laws for <>
~~~~~~~~~~~
<b1>    (x <> y) <> z   = x <> (y <> z)
<b2>    empty <> x      = empty
<b3>    x <> empty      = x

        ...ditto <+>...

Laws for text
~~~~~~~~~~~~~
<t1>    text s <> text t        = text (s++t)
<t2>    text "" <> x            = x, if x non-empty

Laws for nest
~~~~~~~~~~~~~
<n1>    nest 0 x                = x
<n2>    nest k (nest k' x)      = nest (k+k') x
<n3>    nest k (x <> y)         = nest k z <> nest k y
<n4>    nest k (x $$ y)         = nest k x $$ nest k y
<n5>    nest k empty            = empty
<n6>    x <> nest k y           = x <> y, if x non-empty

 - Note the side condition on <n6>!  It is this that
   makes it OK for empty to be a left unit for <>.

Miscellaneous
~~~~~~~~~~~~~
<m1>    (text s <> x) $$ y = text s <> ((text "" <> x)) $$
                                         nest (-length s) y)

<m2>    (x $$ y) <> z = x $$ (y <> z)
        if y non-empty


Laws for list versions
~~~~~~~~~~~~~~~~~~~~~~
<l1>    sep (ps++[empty]++qs)   = sep (ps ++ qs)
        ...ditto hsep, hcat, vcat, fill...

<l2>    nest k (sep ps) = sep (map (nest k) ps)
        ...ditto hsep, hcat, vcat, fill...

Laws for oneLiner
~~~~~~~~~~~~~~~~~
<o1>    oneLiner (nest k p) = nest k (oneLiner p)
<o2>    oneLiner (x <> y)   = oneLiner x <> oneLiner y
\end{verbatim}


You might think that the following verion of <m1> would
be neater:
\begin{verbatim}
<3 NO>  (text s <> x) $$ y = text s <> ((empty <> x)) $$
                                         nest (-length s) y)
\end{verbatim}
But it doesn't work, for if x=empty, we would have
\begin{verbatim}
        text s $$ y = text s <> (empty $$ nest (-length s) y)
                    = text s <> nest (-length s) y
\end{verbatim}



%*********************************************************
%*                                                       *
\subsection{Simple derived definitions}
%*                                                       *
%*********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="semi"></a><span class='hs-definition'>semi</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>';'</span>
<a name="line-2"></a><a name="colon"></a><span class='hs-definition'>colon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>':'</span>
<a name="line-3"></a><a name="comma"></a><span class='hs-definition'>comma</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>','</span>
<a name="line-4"></a><a name="space"></a><span class='hs-definition'>space</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>' '</span>
<a name="line-5"></a><a name="equals"></a><span class='hs-definition'>equals</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'='</span>
<a name="line-6"></a><a name="lparen"></a><span class='hs-definition'>lparen</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'('</span>
<a name="line-7"></a><a name="rparen"></a><span class='hs-definition'>rparen</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>')'</span>
<a name="line-8"></a><a name="lbrack"></a><span class='hs-definition'>lbrack</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'['</span>
<a name="line-9"></a><a name="rbrack"></a><span class='hs-definition'>rbrack</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>']'</span>
<a name="line-10"></a><a name="lbrace"></a><span class='hs-definition'>lbrace</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'{'</span>
<a name="line-11"></a><a name="rbrace"></a><span class='hs-definition'>rbrace</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'}'</span>
<a name="line-12"></a>
<a name="line-13"></a><a name="int"></a><span class='hs-definition'>int</span>      <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>text</span> <span class='hs-layout'>(</span><span class='hs-varid'>show</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span>
<a name="line-14"></a><a name="integer"></a><span class='hs-definition'>integer</span>  <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>text</span> <span class='hs-layout'>(</span><span class='hs-varid'>show</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span>
<a name="line-15"></a><a name="float"></a><span class='hs-definition'>float</span>    <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>text</span> <span class='hs-layout'>(</span><span class='hs-varid'>show</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span>
<a name="line-16"></a><a name="double"></a><span class='hs-definition'>double</span>   <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>text</span> <span class='hs-layout'>(</span><span class='hs-varid'>show</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span>
<a name="line-17"></a><a name="rational"></a><span class='hs-definition'>rational</span> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>text</span> <span class='hs-layout'>(</span><span class='hs-varid'>show</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromRat</span> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Double</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-18"></a><span class='hs-comment'>--rational n = text (show (fromRationalX n)) -- _showRational 30 n)</span>
<a name="line-19"></a>
<a name="line-20"></a><a name="quotes"></a><span class='hs-definition'>quotes</span> <span class='hs-varid'>p</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'`'</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>p</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'\''</span>
<a name="line-21"></a><a name="doubleQuotes"></a><span class='hs-definition'>doubleQuotes</span> <span class='hs-varid'>p</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'"'</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>p</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'"'</span>
<a name="line-22"></a><a name="parens"></a><span class='hs-definition'>parens</span> <span class='hs-varid'>p</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'('</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>p</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>char</span> <span class='hs-chr'>')'</span>
<a name="line-23"></a><a name="brackets"></a><span class='hs-definition'>brackets</span> <span class='hs-varid'>p</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'['</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>p</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>char</span> <span class='hs-chr'>']'</span>
<a name="line-24"></a><a name="braces"></a><span class='hs-definition'>braces</span> <span class='hs-varid'>p</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'{'</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>p</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>char</span> <span class='hs-chr'>'}'</span>
<a name="line-25"></a>
<a name="line-26"></a><a name="cparen"></a><span class='hs-definition'>cparen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-27"></a><span class='hs-definition'>cparen</span> <span class='hs-conid'>True</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parens</span>
<a name="line-28"></a><span class='hs-definition'>cparen</span> <span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>id</span>
<a name="line-29"></a>
<a name="line-30"></a><a name="hcat"></a><span class='hs-definition'>hcat</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varop'>&lt;&gt;</span><span class='hs-layout'>)</span>  <span class='hs-varid'>empty</span>
<a name="line-31"></a><a name="hsep"></a><span class='hs-definition'>hsep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varop'>&lt;+&gt;</span><span class='hs-layout'>)</span> <span class='hs-varid'>empty</span>
<a name="line-32"></a><a name="vcat"></a><span class='hs-definition'>vcat</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-layout'>(</span><span class='hs-varop'>$$</span><span class='hs-layout'>)</span>  <span class='hs-varid'>empty</span>
<a name="line-33"></a>
<a name="line-34"></a><a name="hang"></a><span class='hs-definition'>hang</span> <span class='hs-varid'>d1</span> <span class='hs-varid'>n</span> <span class='hs-varid'>d2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sep</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>d1</span><span class='hs-layout'>,</span> <span class='hs-varid'>nest</span> <span class='hs-varid'>n</span> <span class='hs-varid'>d2</span><span class='hs-keyglyph'>]</span>
<a name="line-35"></a>
<a name="line-36"></a><a name="punctuate"></a><span class='hs-definition'>punctuate</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>[]</span>
<a name="line-37"></a><span class='hs-definition'>punctuate</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>d</span><span class='hs-conop'>:</span><span class='hs-varid'>ds</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>go</span> <span class='hs-varid'>d</span> <span class='hs-varid'>ds</span>
<a name="line-38"></a>                   <span class='hs-keyword'>where</span>
<a name="line-39"></a>                     <span class='hs-varid'>go</span> <span class='hs-varid'>d</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>d</span><span class='hs-keyglyph'>]</span>
<a name="line-40"></a>                     <span class='hs-varid'>go</span> <span class='hs-varid'>d</span> <span class='hs-layout'>(</span><span class='hs-varid'>e</span><span class='hs-conop'>:</span><span class='hs-varid'>es</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>d</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-conop'>:</span> <span class='hs-varid'>go</span> <span class='hs-varid'>e</span> <span class='hs-varid'>es</span>
</pre>\end{code}


%*********************************************************
%*                                                       *
\subsection{The @Doc@ data type}
%*                                                       *
%*********************************************************

A @Doc@ represents a {\em set} of layouts.  A @Doc@ with
no occurrences of @Union@ or @NoDoc@ represents just one layout.
\begin{code}
<pre><a name="line-1"></a><a name="Doc"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Doc</span>
<a name="line-2"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>                                <span class='hs-comment'>-- empty</span>
<a name="line-3"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>NilAbove</span> <span class='hs-conid'>Doc</span>                         <span class='hs-comment'>-- text "" $$ x</span>
<a name="line-4"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>TextBeside</span> <span class='hs-varop'>!</span><span class='hs-conid'>TextDetails</span> <span class='hs-conid'>FastInt</span> <span class='hs-conid'>Doc</span>       <span class='hs-comment'>-- text s &lt;&gt; x</span>
<a name="line-5"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Nest</span> <span class='hs-conid'>FastInt</span> <span class='hs-conid'>Doc</span>                         <span class='hs-comment'>-- nest k x</span>
<a name="line-6"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Union</span> <span class='hs-conid'>Doc</span> <span class='hs-conid'>Doc</span>                        <span class='hs-comment'>-- ul `union` ur</span>
<a name="line-7"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>NoDoc</span>                                <span class='hs-comment'>-- The empty set of documents</span>
<a name="line-8"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Beside</span> <span class='hs-conid'>Doc</span> <span class='hs-conid'>Bool</span> <span class='hs-conid'>Doc</span>                  <span class='hs-comment'>-- True &lt;=&gt; space between</span>
<a name="line-9"></a> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Above</span>  <span class='hs-conid'>Doc</span> <span class='hs-conid'>Bool</span> <span class='hs-conid'>Doc</span>                  <span class='hs-comment'>-- True &lt;=&gt; never overlap</span>
<a name="line-10"></a>
<a name="line-11"></a><a name="RDoc"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Doc</span>         <span class='hs-comment'>-- RDoc is a "reduced Doc", guaranteed not to have a top-level Above or Beside</span>
<a name="line-12"></a>
<a name="line-13"></a>
<a name="line-14"></a><a name="reduceDoc"></a><span class='hs-definition'>reduceDoc</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-15"></a><span class='hs-definition'>reduceDoc</span> <span class='hs-layout'>(</span><span class='hs-conid'>Beside</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>beside</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-16"></a><span class='hs-definition'>reduceDoc</span> <span class='hs-layout'>(</span><span class='hs-conid'>Above</span>  <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>above</span>  <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-17"></a><span class='hs-definition'>reduceDoc</span> <span class='hs-varid'>p</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>p</span>
<a name="line-18"></a>
<a name="line-19"></a>
<a name="line-20"></a><a name="TextDetails"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>TextDetails</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Chr</span>  <span class='hs-comment'>{-#UNPACK#-}</span><span class='hs-varop'>!</span><span class='hs-conid'>Char</span>
<a name="line-21"></a>                 <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Str</span>  <span class='hs-conid'>String</span>
<a name="line-22"></a>                 <span class='hs-keyglyph'>|</span> <span class='hs-conid'>PStr</span> <span class='hs-conid'>FastString</span>                      <span class='hs-comment'>-- a hashed string</span>
<a name="line-23"></a>                 <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LStr</span> <span class='hs-comment'>{-#UNPACK#-}</span><span class='hs-varop'>!</span><span class='hs-conid'>LitString</span> <span class='hs-conid'>FastInt</span>  <span class='hs-comment'>-- a '\0'-terminated</span>
<a name="line-24"></a>                                                        <span class='hs-comment'>-- array of bytes</span>
<a name="line-25"></a>
<a name="line-26"></a><a name="space_text"></a><span class='hs-definition'>space_text</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TextDetails</span>
<a name="line-27"></a><span class='hs-definition'>space_text</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Chr</span> <span class='hs-chr'>' '</span>
<a name="line-28"></a><a name="nl_text"></a><span class='hs-definition'>nl_text</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TextDetails</span>
<a name="line-29"></a><span class='hs-definition'>nl_text</span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Chr</span> <span class='hs-chr'>'\n'</span>
</pre>\end{code}

Here are the invariants:
\begin{itemize}
\item
The argument of @NilAbove@ is never @Empty@. Therefore
a @NilAbove@ occupies at least two lines.

\item
The arugment of @TextBeside@ is never @Nest@.

\item
The layouts of the two arguments of @Union@ both flatten to the same string.

\item
The arguments of @Union@ are either @TextBeside@, or @NilAbove@.

\item
The right argument of a union cannot be equivalent to the empty set (@NoDoc@).
If the left argument of a union is equivalent to the empty set (@NoDoc@),
then the @NoDoc@ appears in the first line.

\item
An empty document is always represented by @Empty@.
It can't be hidden inside a @Nest@, or a @Union@ of two @Empty@s.

\item
The first line of every layout in the left argument of @Union@
is longer than the first line of any layout in the right argument.
(1) ensures that the left argument has a first line.  In view of (3),
this invariant means that the right argument must have at least two
lines.
\end{itemize}

\begin{code}
<pre><a name="line-1"></a><a name="nilAbove_"></a><span class='hs-comment'>-- Arg of a NilAbove is always an RDoc</span>
<a name="line-2"></a><span class='hs-definition'>nilAbove_</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-3"></a><span class='hs-definition'>nilAbove_</span> <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LOCAL_ASSERT</span><span class='hs-layout'>(</span> <span class='hs-sel'>_ok</span> <span class='hs-varid'>p</span> <span class='hs-layout'>)</span> <span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span>
<a name="line-4"></a>            <span class='hs-keyword'>where</span>
<a name="line-5"></a>              <span class='hs-sel'>_ok</span> <span class='hs-conid'>Empty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-6"></a>              <span class='hs-sel'>_ok</span> <span class='hs-keyword'>_</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-7"></a>
<a name="line-8"></a><a name="textBeside_"></a><span class='hs-comment'>-- Arg of a TextBeside is always an RDoc</span>
<a name="line-9"></a><span class='hs-definition'>textBeside_</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TextDetails</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-10"></a><span class='hs-definition'>textBeside_</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-conid'>LOCAL_ASSERT</span><span class='hs-layout'>(</span> <span class='hs-sel'>_ok</span> <span class='hs-varid'>p</span> <span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-11"></a>                   <span class='hs-keyword'>where</span>
<a name="line-12"></a>                     <span class='hs-sel'>_ok</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-13"></a>                     <span class='hs-sel'>_ok</span> <span class='hs-keyword'>_</span>          <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-14"></a>
<a name="line-15"></a><a name="nest_"></a><span class='hs-comment'>-- Arg of Nest is always an RDoc</span>
<a name="line-16"></a><span class='hs-definition'>nest_</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-17"></a><span class='hs-definition'>nest_</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nest</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>LOCAL_ASSERT</span><span class='hs-layout'>(</span> <span class='hs-sel'>_ok</span> <span class='hs-varid'>p</span> <span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-18"></a>          <span class='hs-keyword'>where</span>
<a name="line-19"></a>            <span class='hs-sel'>_ok</span> <span class='hs-conid'>Empty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-20"></a>            <span class='hs-sel'>_ok</span> <span class='hs-keyword'>_</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-21"></a>
<a name="line-22"></a><a name="union_"></a><span class='hs-comment'>-- Args of union are always RDocs</span>
<a name="line-23"></a><span class='hs-definition'>union_</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-24"></a><span class='hs-definition'>union_</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Union</span> <span class='hs-layout'>(</span><span class='hs-conid'>LOCAL_ASSERT</span><span class='hs-layout'>(</span> <span class='hs-sel'>_ok</span> <span class='hs-varid'>p</span> <span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>LOCAL_ASSERT</span><span class='hs-layout'>(</span> <span class='hs-sel'>_ok</span> <span class='hs-varid'>q</span> <span class='hs-layout'>)</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-25"></a>           <span class='hs-keyword'>where</span>
<a name="line-26"></a>             <span class='hs-sel'>_ok</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-27"></a>             <span class='hs-sel'>_ok</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-28"></a>             <span class='hs-sel'>_ok</span> <span class='hs-layout'>(</span><span class='hs-conid'>Union</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-29"></a>             <span class='hs-sel'>_ok</span> <span class='hs-keyword'>_</span>                  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
</pre>\end{code}

Notice the difference between
        * NoDoc (no documents)
        * Empty (one empty document; no height and no width)
        * text "" (a document containing the empty string;
                   one line high, but has no width)



%*********************************************************
%*                                                       *
\subsection{@empty@, @text@, @nest@, @union@}
%*                                                       *
%*********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="empty"></a><span class='hs-definition'>empty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>
<a name="line-2"></a>
<a name="line-3"></a><a name="isEmpty"></a><span class='hs-definition'>isEmpty</span> <span class='hs-conid'>Empty</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-4"></a><span class='hs-definition'>isEmpty</span> <span class='hs-keyword'>_</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-5"></a>
<a name="line-6"></a><a name="char"></a><span class='hs-definition'>char</span>  <span class='hs-varid'>c</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-layout'>(</span><span class='hs-conid'>Chr</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-conid'>Empty</span>
<a name="line-7"></a><a name="text"></a><span class='hs-definition'>text</span>  <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>iUnbox</span> <span class='hs-layout'>(</span><span class='hs-varid'>length</span>   <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span><span class='hs-varid'>sl</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>textBeside_</span> <span class='hs-layout'>(</span><span class='hs-conid'>Str</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>  <span class='hs-varid'>sl</span> <span class='hs-conid'>Empty</span><span class='hs-layout'>}</span>
<a name="line-8"></a><a name="ftext"></a><span class='hs-definition'>ftext</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastString</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-9"></a><span class='hs-definition'>ftext</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>iUnbox</span> <span class='hs-layout'>(</span><span class='hs-varid'>lengthFS</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span><span class='hs-varid'>sl</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>textBeside_</span> <span class='hs-layout'>(</span><span class='hs-conid'>PStr</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-varid'>sl</span> <span class='hs-conid'>Empty</span><span class='hs-layout'>}</span>
<a name="line-10"></a><a name="ptext"></a><span class='hs-definition'>ptext</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LitString</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-11"></a><span class='hs-definition'>ptext</span> <span class='hs-varid'>s_</span><span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>iUnbox</span> <span class='hs-layout'>(</span><span class='hs-varid'>lengthLS</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span><span class='hs-varid'>sl</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>textBeside_</span> <span class='hs-layout'>(</span><span class='hs-conid'>LStr</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>sl</span> <span class='hs-conid'>Empty</span><span class='hs-layout'>}</span>
<a name="line-12"></a>  <span class='hs-keyword'>where</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-comment'>{-castPtr-}</span> <span class='hs-varid'>s_</span>
<a name="line-13"></a>
<a name="line-14"></a><span class='hs-cpp'>#if defined(__GLASGOW_HASKELL__)</span>
<a name="line-15"></a><span class='hs-comment'>-- RULE that turns (text "abc") into (ptext (A# "abc"#)) to avoid the</span>
<a name="line-16"></a><span class='hs-comment'>-- intermediate packing/unpacking of the string.</span>
<a name="line-17"></a><span class='hs-comment'>{-# RULES
<a name="line-18"></a>  "text/str" forall a. text (unpackCString# a) = ptext (Ptr a)
<a name="line-19"></a> #-}</span>
<a name="line-20"></a><span class='hs-cpp'>#endif</span>
<a name="line-21"></a>
<a name="line-22"></a><a name="nest"></a><span class='hs-definition'>nest</span> <span class='hs-varid'>k</span>  <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkNest</span> <span class='hs-layout'>(</span><span class='hs-varid'>iUnbox</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-comment'>-- Externally callable version</span>
<a name="line-23"></a>
<a name="line-24"></a><a name="mkNest"></a><span class='hs-comment'>-- mkNest checks for Nest's invariant that it doesn't have an Empty inside it</span>
<a name="line-25"></a><span class='hs-definition'>mkNest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span><span class='hs-cpp'>#</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-26"></a><span class='hs-definition'>mkNest</span> <span class='hs-varid'>k</span>       <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>k1</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkNest</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>+#</span> <span class='hs-varid'>k1</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span>
<a name="line-27"></a><span class='hs-definition'>mkNest</span> <span class='hs-keyword'>_</span>       <span class='hs-conid'>NoDoc</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-28"></a><span class='hs-definition'>mkNest</span> <span class='hs-keyword'>_</span>       <span class='hs-conid'>Empty</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>
<a name="line-29"></a><span class='hs-definition'>mkNest</span> <span class='hs-varid'>k</span>       <span class='hs-varid'>p</span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>k</span> <span class='hs-varop'>==#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>p</span>       <span class='hs-comment'>-- Worth a try!</span>
<a name="line-30"></a><span class='hs-definition'>mkNest</span> <span class='hs-varid'>k</span>       <span class='hs-varid'>p</span>           <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nest_</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span>
<a name="line-31"></a>
<a name="line-32"></a><a name="mkUnion"></a><span class='hs-comment'>-- mkUnion checks for an empty document</span>
<a name="line-33"></a><span class='hs-definition'>mkUnion</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-34"></a><span class='hs-definition'>mkUnion</span> <span class='hs-conid'>Empty</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>
<a name="line-35"></a><span class='hs-definition'>mkUnion</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>p</span> <span class='hs-varop'>`union_`</span> <span class='hs-varid'>q</span>
</pre>\end{code}

%*********************************************************
%*                                                       *
\subsection{Vertical composition @$$@}
%*                                                       *
%*********************************************************


\begin{code}
<pre><a name="line-1"></a><a name="$$"></a><span class='hs-definition'>p</span> <span class='hs-varop'>$$</span>  <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Above</span> <span class='hs-varid'>p</span> <span class='hs-conid'>False</span> <span class='hs-varid'>q</span>
<a name="line-2"></a><a name="$+$"></a><span class='hs-layout'>(</span><span class='hs-varop'>$+$</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-3"></a><a name="p"></a><span class='hs-definition'>p</span> <span class='hs-varop'>$+$</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Above</span> <span class='hs-varid'>p</span> <span class='hs-conid'>True</span> <span class='hs-varid'>q</span>
<a name="line-4"></a>
<a name="line-5"></a><a name="above"></a><span class='hs-definition'>above</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-6"></a><span class='hs-definition'>above</span> <span class='hs-layout'>(</span><span class='hs-conid'>Above</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g1</span> <span class='hs-varid'>q1</span><span class='hs-layout'>)</span>  <span class='hs-varid'>g2</span> <span class='hs-varid'>q2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>above</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g1</span> <span class='hs-layout'>(</span><span class='hs-varid'>above</span> <span class='hs-varid'>q1</span> <span class='hs-varid'>g2</span> <span class='hs-varid'>q2</span><span class='hs-layout'>)</span>
<a name="line-7"></a><span class='hs-definition'>above</span> <span class='hs-varid'>p</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Beside</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span>  <span class='hs-varid'>q</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>aboveNest</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-8"></a><span class='hs-definition'>above</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>                  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>aboveNest</span> <span class='hs-varid'>p</span>             <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-9"></a>
<a name="line-10"></a><a name="aboveNest"></a><span class='hs-definition'>aboveNest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-11"></a><span class='hs-comment'>-- Specfication: aboveNest p g k q = p $g$ (nest k q)</span>
<a name="line-12"></a>
<a name="line-13"></a><span class='hs-definition'>aboveNest</span> <span class='hs-conid'>NoDoc</span>               <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-14"></a><span class='hs-definition'>aboveNest</span> <span class='hs-layout'>(</span><span class='hs-varid'>p1</span> <span class='hs-varop'>`Union`</span> <span class='hs-varid'>p2</span><span class='hs-layout'>)</span>     <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>aboveNest</span> <span class='hs-varid'>p1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span> <span class='hs-varop'>`union_`</span>
<a name="line-15"></a>                                      <span class='hs-varid'>aboveNest</span> <span class='hs-varid'>p2</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span>
<a name="line-16"></a>
<a name="line-17"></a><span class='hs-definition'>aboveNest</span> <span class='hs-conid'>Empty</span>               <span class='hs-keyword'>_</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkNest</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span>
<a name="line-18"></a><span class='hs-definition'>aboveNest</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>k1</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>         <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nest_</span> <span class='hs-varid'>k1</span> <span class='hs-layout'>(</span><span class='hs-varid'>aboveNest</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>k1</span><span class='hs-layout'>)</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-19"></a>                                  <span class='hs-comment'>-- p can't be Empty, so no need for mkNest</span>
<a name="line-20"></a>
<a name="line-21"></a><span class='hs-definition'>aboveNest</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAbove_</span> <span class='hs-layout'>(</span><span class='hs-varid'>aboveNest</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-22"></a><span class='hs-definition'>aboveNest</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>rest</span>
<a name="line-23"></a>                                    <span class='hs-keyword'>where</span>
<a name="line-24"></a>                                      <span class='hs-varop'>!</span><span class='hs-varid'>k1</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>sl</span>
<a name="line-25"></a>                                      <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>p</span> <span class='hs-keyword'>of</span>
<a name="line-26"></a>                                                <span class='hs-conid'>Empty</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>nilAboveNest</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k1</span> <span class='hs-varid'>q</span>
<a name="line-27"></a>                                                <span class='hs-keyword'>_</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>aboveNest</span>  <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k1</span> <span class='hs-varid'>q</span>
<a name="line-28"></a><span class='hs-definition'>aboveNest</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"aboveNest: Unhandled case"</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="nilAboveNest"></a><span class='hs-definition'>nilAboveNest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-2"></a><span class='hs-comment'>-- Specification: text s &lt;&gt; nilaboveNest g k q</span>
<a name="line-3"></a><span class='hs-comment'>--              = text s &lt;&gt; (text "" $g$ nest k q)</span>
<a name="line-4"></a>
<a name="line-5"></a><span class='hs-definition'>nilAboveNest</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Empty</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>    <span class='hs-comment'>-- Here's why the "text s &lt;&gt;" is in the spec!</span>
<a name="line-6"></a><span class='hs-definition'>nilAboveNest</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>k1</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAboveNest</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>+#</span> <span class='hs-varid'>k1</span><span class='hs-layout'>)</span> <span class='hs-varid'>q</span>
<a name="line-7"></a>
<a name="line-8"></a><span class='hs-definition'>nilAboveNest</span> <span class='hs-varid'>g</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span>           <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>not</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>&gt;#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>        <span class='hs-comment'>-- No newline if no overlap</span>
<a name="line-9"></a>                             <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-layout'>(</span><span class='hs-conid'>Str</span> <span class='hs-layout'>(</span><span class='hs-varid'>spaces</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span>
<a name="line-10"></a>                             <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>                        <span class='hs-comment'>-- Put them really above</span>
<a name="line-11"></a>                             <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAbove_</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkNest</span> <span class='hs-varid'>k</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
</pre>\end{code}


%*********************************************************
%*                                                       *
\subsection{Horizontal composition @<>@}
%*                                                       *
%*********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="<>"></a><span class='hs-definition'>p</span> <span class='hs-varop'>&lt;&gt;</span>  <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Beside</span> <span class='hs-varid'>p</span> <span class='hs-conid'>False</span> <span class='hs-varid'>q</span>
<a name="line-2"></a><a name="<+>"></a><span class='hs-definition'>p</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Beside</span> <span class='hs-varid'>p</span> <span class='hs-conid'>True</span>  <span class='hs-varid'>q</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="beside"></a><span class='hs-definition'>beside</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-5"></a><span class='hs-comment'>-- Specification: beside g p q = p &lt;g&gt; q</span>
<a name="line-6"></a>
<a name="line-7"></a><span class='hs-definition'>beside</span> <span class='hs-conid'>NoDoc</span>               <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-8"></a><span class='hs-definition'>beside</span> <span class='hs-layout'>(</span><span class='hs-varid'>p1</span> <span class='hs-varop'>`Union`</span> <span class='hs-varid'>p2</span><span class='hs-layout'>)</span>     <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>   <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>beside</span> <span class='hs-varid'>p1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span> <span class='hs-varop'>`union_`</span> <span class='hs-layout'>(</span><span class='hs-varid'>beside</span> <span class='hs-varid'>p2</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-9"></a><span class='hs-definition'>beside</span> <span class='hs-conid'>Empty</span>               <span class='hs-keyword'>_</span> <span class='hs-varid'>q</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>q</span>
<a name="line-10"></a><span class='hs-definition'>beside</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>          <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nest_</span> <span class='hs-varid'>k</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>beside</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>       <span class='hs-comment'>-- p non-empty</span>
<a name="line-11"></a><span class='hs-definition'>beside</span> <span class='hs-varid'>p</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Beside</span> <span class='hs-varid'>p1</span> <span class='hs-varid'>g1</span> <span class='hs-varid'>q1</span><span class='hs-layout'>)</span> <span class='hs-varid'>g2</span> <span class='hs-varid'>q2</span>
<a name="line-12"></a>           <span class='hs-comment'>{- (A `op1` B) `op2` C == A `op1` (B `op2` C)  iff op1 == op2
<a name="line-13"></a>                                                 [ &amp;&amp; (op1 == &lt;&gt; || op1 == &lt;+&gt;) ] -}</span>
<a name="line-14"></a>         <span class='hs-keyglyph'>|</span> <span class='hs-varid'>g1</span> <span class='hs-varop'>==</span> <span class='hs-varid'>g2</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>beside</span> <span class='hs-varid'>p1</span> <span class='hs-varid'>g1</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>beside</span> <span class='hs-varid'>q1</span> <span class='hs-varid'>g2</span> <span class='hs-varid'>q2</span>
<a name="line-15"></a>         <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>             <span class='hs-keyglyph'>=</span> <span class='hs-varid'>beside</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>g2</span> <span class='hs-varid'>q2</span>
<a name="line-16"></a><span class='hs-definition'>beside</span> <span class='hs-varid'>p</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Above</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>     <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>   <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-varid'>d</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>p</span> <span class='hs-keyword'>in</span> <span class='hs-varid'>d</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>beside</span> <span class='hs-varid'>d</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>
<a name="line-17"></a><span class='hs-definition'>beside</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAbove_</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>beside</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>
<a name="line-18"></a><span class='hs-definition'>beside</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varop'>$!</span> <span class='hs-varid'>rest</span>
<a name="line-19"></a>                               <span class='hs-keyword'>where</span>
<a name="line-20"></a>                                  <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>p</span> <span class='hs-keyword'>of</span>
<a name="line-21"></a>                                           <span class='hs-conid'>Empty</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>nilBeside</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>
<a name="line-22"></a>                                           <span class='hs-keyword'>_</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>beside</span> <span class='hs-varid'>p</span> <span class='hs-varid'>g</span> <span class='hs-varid'>q</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="nilBeside"></a><span class='hs-definition'>nilBeside</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-2"></a><span class='hs-comment'>-- Specification: text "" &lt;&gt; nilBeside g p</span>
<a name="line-3"></a><span class='hs-comment'>--              = text "" &lt;g&gt; p</span>
<a name="line-4"></a>
<a name="line-5"></a><span class='hs-definition'>nilBeside</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Empty</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>  <span class='hs-comment'>-- Hence the text "" in the spec</span>
<a name="line-6"></a><span class='hs-definition'>nilBeside</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilBeside</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span>
<a name="line-7"></a><span class='hs-definition'>nilBeside</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span>          <span class='hs-keyglyph'>|</span> <span class='hs-varid'>g</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>space_text</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span>
<a name="line-8"></a>                       <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>p</span>
</pre>\end{code}

%*********************************************************
%*                                                       *
\subsection{Separate, @sep@, Hughes version}
%*                                                       *
%*********************************************************

\begin{code}
<pre><a name="line-1"></a><span class='hs-comment'>-- Specification: sep ps  = oneLiner (hsep ps)</span>
<a name="line-2"></a><span class='hs-comment'>--                         `union`</span>
<a name="line-3"></a><span class='hs-comment'>--                          vcat ps</span>
<a name="line-4"></a>
<a name="line-5"></a><a name="sep"></a><span class='hs-definition'>sep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sepX</span> <span class='hs-conid'>True</span>         <span class='hs-comment'>-- Separate with spaces</span>
<a name="line-6"></a><a name="cat"></a><span class='hs-definition'>cat</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sepX</span> <span class='hs-conid'>False</span>        <span class='hs-comment'>-- Don't</span>
<a name="line-7"></a>
<a name="line-8"></a><a name="sepX"></a><span class='hs-definition'>sepX</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-9"></a><span class='hs-definition'>sepX</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>empty</span>
<a name="line-10"></a><span class='hs-definition'>sepX</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span><span class='hs-conop'>:</span><span class='hs-varid'>ps</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sep1</span> <span class='hs-varid'>x</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>ps</span>
<a name="line-11"></a>
<a name="line-12"></a>
<a name="line-13"></a><span class='hs-comment'>-- Specification: sep1 g k ys = sep (x : map (nest k) ys)</span>
<a name="line-14"></a><span class='hs-comment'>--                            = oneLiner (x &lt;g&gt; nest k (hsep ys))</span>
<a name="line-15"></a><span class='hs-comment'>--                              `union` x $$ nest k (vcat ys)</span>
<a name="line-16"></a>
<a name="line-17"></a><a name="sep1"></a><span class='hs-definition'>sep1</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-18"></a><span class='hs-definition'>sep1</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>NoDoc</span>               <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-19"></a><span class='hs-definition'>sep1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varop'>`Union`</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>       <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sep1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>
<a name="line-20"></a>                                  <span class='hs-varop'>`union_`</span>
<a name="line-21"></a>                                  <span class='hs-layout'>(</span><span class='hs-varid'>aboveNest</span> <span class='hs-varid'>q</span> <span class='hs-conid'>False</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-layout'>(</span><span class='hs-varid'>vcat</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-22"></a>
<a name="line-23"></a><span class='hs-definition'>sep1</span> <span class='hs-varid'>g</span> <span class='hs-conid'>Empty</span>               <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkNest</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>sepX</span> <span class='hs-varid'>g</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span>
<a name="line-24"></a><span class='hs-definition'>sep1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>n</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>          <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nest_</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-varid'>sep1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span>
<a name="line-25"></a>
<a name="line-26"></a><span class='hs-definition'>sep1</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAbove_</span> <span class='hs-layout'>(</span><span class='hs-varid'>aboveNest</span> <span class='hs-varid'>p</span> <span class='hs-conid'>False</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-layout'>(</span><span class='hs-varid'>vcat</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-27"></a><span class='hs-definition'>sep1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-varid'>sepNB</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span>
<a name="line-28"></a><span class='hs-definition'>sep1</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"sep1: Unhandled case"</span>
<a name="line-29"></a>
<a name="line-30"></a><span class='hs-comment'>-- Specification: sepNB p k ys = sep1 (text "" &lt;&gt; p) k ys</span>
<a name="line-31"></a><span class='hs-comment'>-- Called when we have already found some text in the first item</span>
<a name="line-32"></a><span class='hs-comment'>-- We have to eat up nests</span>
<a name="line-33"></a>
<a name="line-34"></a><a name="sepNB"></a><span class='hs-definition'>sepNB</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-35"></a><span class='hs-definition'>sepNB</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>  <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sepNB</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>
<a name="line-36"></a>
<a name="line-37"></a><span class='hs-definition'>sepNB</span> <span class='hs-varid'>g</span> <span class='hs-conid'>Empty</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>oneLiner</span> <span class='hs-layout'>(</span><span class='hs-varid'>nilBeside</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>rest</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-38"></a>                                <span class='hs-varop'>`mkUnion`</span>
<a name="line-39"></a>                            <span class='hs-varid'>nilAboveNest</span> <span class='hs-conid'>False</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-layout'>(</span><span class='hs-varid'>vcat</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-40"></a>                          <span class='hs-keyword'>where</span>
<a name="line-41"></a>                            <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>g</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hsep</span> <span class='hs-varid'>ys</span>
<a name="line-42"></a>                                 <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hcat</span> <span class='hs-varid'>ys</span>
<a name="line-43"></a>
<a name="line-44"></a><span class='hs-definition'>sepNB</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>            <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sep1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>
</pre>\end{code}

%*********************************************************
%*                                                       *
\subsection{@fill@}
%*                                                       *
%*********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="fsep"></a><span class='hs-definition'>fsep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fill</span> <span class='hs-conid'>True</span>
<a name="line-2"></a><a name="fcat"></a><span class='hs-definition'>fcat</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fill</span> <span class='hs-conid'>False</span>
<a name="line-3"></a>
<a name="line-4"></a><span class='hs-comment'>-- Specification:</span>
<a name="line-5"></a><span class='hs-comment'>--   fill []  = empty</span>
<a name="line-6"></a><span class='hs-comment'>--   fill [p] = p</span>
<a name="line-7"></a><span class='hs-comment'>--   fill (p1:p2:ps) = oneLiner p1 &lt;#&gt; nest (length p1)</span>
<a name="line-8"></a><span class='hs-comment'>--                                          (fill (oneLiner p2 : ps))</span>
<a name="line-9"></a><span class='hs-comment'>--                     `union`</span>
<a name="line-10"></a><span class='hs-comment'>--                      p1 $$ fill ps</span>
<a name="line-11"></a>
<a name="line-12"></a><a name="fill"></a><span class='hs-definition'>fill</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-13"></a><span class='hs-definition'>fill</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>empty</span>
<a name="line-14"></a><span class='hs-definition'>fill</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span><span class='hs-conop'>:</span><span class='hs-varid'>ps</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>ps</span>
<a name="line-15"></a>
<a name="line-16"></a>
<a name="line-17"></a><a name="fill1"></a><span class='hs-definition'>fill1</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-18"></a><span class='hs-definition'>fill1</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>NoDoc</span>               <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-19"></a><span class='hs-definition'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varop'>`Union`</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>       <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>
<a name="line-20"></a>                                   <span class='hs-varop'>`union_`</span>
<a name="line-21"></a>                                   <span class='hs-layout'>(</span><span class='hs-varid'>aboveNest</span> <span class='hs-varid'>q</span> <span class='hs-conid'>False</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>fill</span> <span class='hs-varid'>g</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-22"></a>
<a name="line-23"></a><span class='hs-definition'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-conid'>Empty</span>               <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkNest</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>fill</span> <span class='hs-varid'>g</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span>
<a name="line-24"></a><span class='hs-definition'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>n</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>          <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nest_</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-varid'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span>
<a name="line-25"></a>
<a name="line-26"></a><span class='hs-definition'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAbove_</span> <span class='hs-layout'>(</span><span class='hs-varid'>aboveNest</span> <span class='hs-varid'>p</span> <span class='hs-conid'>False</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>fill</span> <span class='hs-varid'>g</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-27"></a><span class='hs-definition'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-varid'>fillNB</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span>
<a name="line-28"></a><span class='hs-definition'>fill1</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"fill1: Unhandled case"</span>
<a name="line-29"></a>
<a name="line-30"></a><a name="fillNB"></a><span class='hs-definition'>fillNB</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-cpp'>#</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Doc</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-31"></a><span class='hs-definition'>fillNB</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>  <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fillNB</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>
<a name="line-32"></a><span class='hs-definition'>fillNB</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Empty</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>
<a name="line-33"></a><span class='hs-definition'>fillNB</span> <span class='hs-varid'>g</span> <span class='hs-conid'>Empty</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-varid'>ys</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilBeside</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>oneLiner</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>k1</span> <span class='hs-varid'>ys</span><span class='hs-layout'>)</span>
<a name="line-34"></a>                             <span class='hs-varop'>`mkUnion`</span>
<a name="line-35"></a>                             <span class='hs-varid'>nilAboveNest</span> <span class='hs-conid'>False</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>fill</span> <span class='hs-varid'>g</span> <span class='hs-layout'>(</span><span class='hs-varid'>y</span><span class='hs-conop'>:</span><span class='hs-varid'>ys</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-36"></a>                           <span class='hs-keyword'>where</span>
<a name="line-37"></a>                             <span class='hs-varop'>!</span><span class='hs-varid'>k1</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>g</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>1</span><span class='hs-layout'>)</span>
<a name="line-38"></a>                                 <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>k</span>
<a name="line-39"></a>
<a name="line-40"></a><span class='hs-definition'>fillNB</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>            <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fill1</span> <span class='hs-varid'>g</span> <span class='hs-varid'>p</span> <span class='hs-varid'>k</span> <span class='hs-varid'>ys</span>
</pre>\end{code}


%*********************************************************
%*                                                       *
\subsection{Selecting the best layout}
%*                                                       *
%*********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="best"></a><span class='hs-definition'>best</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>             <span class='hs-comment'>-- Line length</span>
<a name="line-2"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>             <span class='hs-comment'>-- Ribbon length</span>
<a name="line-3"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>
<a name="line-4"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RDoc</span>            <span class='hs-comment'>-- No unions in here!</span>
<a name="line-5"></a>
<a name="line-6"></a><span class='hs-definition'>best</span> <span class='hs-varid'>w_</span> <span class='hs-varid'>r_</span> <span class='hs-varid'>p</span>
<a name="line-7"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>get</span> <span class='hs-layout'>(</span><span class='hs-varid'>iUnbox</span> <span class='hs-varid'>w_</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span>
<a name="line-8"></a>  <span class='hs-keyword'>where</span>
<a name="line-9"></a>    <span class='hs-varop'>!</span><span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>iUnbox</span> <span class='hs-varid'>r_</span>
<a name="line-10"></a>    <span class='hs-varid'>get</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastInt</span>          <span class='hs-comment'>-- (Remaining) width of line</span>
<a name="line-11"></a>        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-12"></a>    <span class='hs-varid'>get</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Empty</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>
<a name="line-13"></a>    <span class='hs-varid'>get</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>NoDoc</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-14"></a>    <span class='hs-varid'>get</span> <span class='hs-varid'>w</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAbove_</span> <span class='hs-layout'>(</span><span class='hs-varid'>get</span> <span class='hs-varid'>w</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-15"></a>    <span class='hs-varid'>get</span> <span class='hs-varid'>w</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-16"></a>    <span class='hs-varid'>get</span> <span class='hs-varid'>w</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>          <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nest_</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>get</span> <span class='hs-layout'>(</span><span class='hs-varid'>w</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-17"></a>    <span class='hs-varid'>get</span> <span class='hs-varid'>w</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varop'>`Union`</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nicest</span> <span class='hs-varid'>w</span> <span class='hs-varid'>r</span> <span class='hs-layout'>(</span><span class='hs-varid'>get</span> <span class='hs-varid'>w</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>get</span> <span class='hs-varid'>w</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-18"></a>    <span class='hs-varid'>get</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"best/get: Unhandled case"</span>
<a name="line-19"></a>
<a name="line-20"></a>    <span class='hs-varid'>get1</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastInt</span>         <span class='hs-comment'>-- (Remaining) width of line</span>
<a name="line-21"></a>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span>         <span class='hs-comment'>-- Amount of first line already eaten up</span>
<a name="line-22"></a>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>         <span class='hs-comment'>-- This is an argument to TextBeside =&gt; eat Nests</span>
<a name="line-23"></a>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>         <span class='hs-comment'>-- No unions in here!</span>
<a name="line-24"></a>
<a name="line-25"></a>    <span class='hs-varid'>get1</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>  <span class='hs-conid'>Empty</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>
<a name="line-26"></a>    <span class='hs-varid'>get1</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>  <span class='hs-conid'>NoDoc</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-27"></a>    <span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nilAbove_</span> <span class='hs-layout'>(</span><span class='hs-varid'>get</span> <span class='hs-layout'>(</span><span class='hs-varid'>w</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-28"></a>    <span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>t</span> <span class='hs-varid'>tl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>t</span> <span class='hs-varid'>tl</span> <span class='hs-layout'>(</span><span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-layout'>(</span><span class='hs-varid'>sl</span> <span class='hs-varop'>+#</span> <span class='hs-varid'>tl</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-29"></a>    <span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>          <span class='hs-keyglyph'>=</span> <span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span>
<a name="line-30"></a>    <span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varop'>`Union`</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nicest1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>r</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-31"></a>                                                   <span class='hs-layout'>(</span><span class='hs-varid'>get1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-32"></a>    <span class='hs-varid'>get1</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>  <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"best/get1: Unhandled case"</span>
<a name="line-33"></a>
<a name="line-34"></a><a name="nicest"></a><span class='hs-definition'>nicest</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-35"></a><span class='hs-definition'>nicest</span> <span class='hs-varid'>w</span> <span class='hs-varid'>r</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nicest1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>r</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span>
<a name="line-36"></a><a name="nicest1"></a><span class='hs-definition'>nicest1</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FastInt</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-cpp'>#</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-37"></a><span class='hs-definition'>nicest1</span> <span class='hs-varid'>w</span> <span class='hs-varid'>r</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>fits</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>w</span> <span class='hs-varop'>`minFastInt`</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>p</span>
<a name="line-38"></a>                   <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>q</span>
<a name="line-39"></a>
<a name="line-40"></a><a name="fits"></a><span class='hs-definition'>fits</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FastInt</span>     <span class='hs-comment'>-- Space available</span>
<a name="line-41"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-42"></a>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>    <span class='hs-comment'>-- True if *first line* of Doc fits in space available</span>
<a name="line-43"></a>
<a name="line-44"></a><span class='hs-definition'>fits</span> <span class='hs-varid'>n</span> <span class='hs-keyword'>_</span>   <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&lt;#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-45"></a><span class='hs-definition'>fits</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>NoDoc</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-46"></a><span class='hs-definition'>fits</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Empty</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-47"></a><span class='hs-definition'>fits</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-48"></a><span class='hs-definition'>fits</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fits</span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span>
<a name="line-49"></a><span class='hs-definition'>fits</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"fits: Unhandled case"</span>
</pre>\end{code}

@first@ and @nonEmptySet@ are similar to @nicest@ and @fits@, only simpler.
@first@ returns its first argument if it is non-empty, otherwise its second.

\begin{code}
<pre><a name="line-1"></a><a name="first"></a><span class='hs-definition'>first</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-2"></a><span class='hs-definition'>first</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>nonEmptySet</span> <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>p</span>
<a name="line-3"></a>          <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>q</span>
<a name="line-4"></a>
<a name="line-5"></a><a name="nonEmptySet"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-6"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-conid'>NoDoc</span>              <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-7"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span> <span class='hs-varop'>`Union`</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-8"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-conid'>Empty</span>              <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-9"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>           <span class='hs-comment'>-- NoDoc always in first line</span>
<a name="line-10"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nonEmptySet</span> <span class='hs-varid'>p</span>
<a name="line-11"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nonEmptySet</span> <span class='hs-varid'>p</span>
<a name="line-12"></a><span class='hs-definition'>nonEmptySet</span> <span class='hs-keyword'>_</span>                  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"nonEmptySet: Unhandled case"</span>
</pre>\end{code}

@oneLiner@ returns the one-line members of the given set of @Doc@s.

\begin{code}
<pre><a name="line-1"></a><a name="oneLiner"></a><span class='hs-definition'>oneLiner</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span>
<a name="line-2"></a><span class='hs-definition'>oneLiner</span> <span class='hs-conid'>NoDoc</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-3"></a><span class='hs-definition'>oneLiner</span> <span class='hs-conid'>Empty</span>               <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Empty</span>
<a name="line-4"></a><span class='hs-definition'>oneLiner</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoDoc</span>
<a name="line-5"></a><span class='hs-definition'>oneLiner</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>textBeside_</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-layout'>(</span><span class='hs-varid'>oneLiner</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-6"></a><span class='hs-definition'>oneLiner</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>          <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nest_</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>oneLiner</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-7"></a><span class='hs-definition'>oneLiner</span> <span class='hs-layout'>(</span><span class='hs-varid'>p</span> <span class='hs-varop'>`Union`</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>oneLiner</span> <span class='hs-varid'>p</span>
<a name="line-8"></a><span class='hs-definition'>oneLiner</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"oneLiner: Unhandled case"</span>
</pre>\end{code}



%*********************************************************
%*                                                       *
\subsection{Displaying the best layout}
%*                                                       *
%*********************************************************


\begin{code}
<pre><a name="line-1"></a><span class='hs-comment'>{-
<a name="line-2"></a>renderStyle Style{mode, lineLength, ribbonsPerLine} doc
<a name="line-3"></a>  = fullRender mode lineLength ribbonsPerLine doc ""
<a name="line-4"></a>-}</span>
<a name="line-5"></a>
<a name="line-6"></a><a name="render"></a><span class='hs-definition'>render</span> <span class='hs-varid'>doc</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>showDocWith</span> <span class='hs-conid'>PageMode</span> <span class='hs-varid'>doc</span>
<a name="line-7"></a>
<a name="line-8"></a><a name="showDoc"></a><span class='hs-definition'>showDoc</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-9"></a><span class='hs-definition'>showDoc</span> <span class='hs-varid'>doc</span> <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>showDocWithAppend</span> <span class='hs-conid'>PageMode</span> <span class='hs-varid'>doc</span> <span class='hs-varid'>rest</span>
<a name="line-10"></a>
<a name="line-11"></a><a name="showDocWithAppend"></a><span class='hs-definition'>showDocWithAppend</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Mode</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-12"></a><span class='hs-definition'>showDocWithAppend</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>doc</span> <span class='hs-varid'>rest</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fullRender</span> <span class='hs-varid'>mode</span> <span class='hs-num'>100</span> <span class='hs-num'>1.5</span> <span class='hs-varid'>string_txt</span> <span class='hs-varid'>rest</span> <span class='hs-varid'>doc</span>
<a name="line-13"></a>
<a name="line-14"></a><a name="showDocWith"></a><span class='hs-definition'>showDocWith</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Mode</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-15"></a><span class='hs-definition'>showDocWith</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>doc</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>showDocWithAppend</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>doc</span> <span class='hs-str'>""</span>
<a name="line-16"></a>
<a name="line-17"></a><a name="string_txt"></a><span class='hs-definition'>string_txt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TextDetails</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-18"></a><span class='hs-definition'>string_txt</span> <span class='hs-layout'>(</span><span class='hs-conid'>Chr</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>   <span class='hs-varid'>s</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>c</span><span class='hs-conop'>:</span><span class='hs-varid'>s</span>
<a name="line-19"></a><span class='hs-definition'>string_txt</span> <span class='hs-layout'>(</span><span class='hs-conid'>Str</span> <span class='hs-varid'>s1</span><span class='hs-layout'>)</span>  <span class='hs-varid'>s2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s1</span> <span class='hs-varop'>++</span> <span class='hs-varid'>s2</span>
<a name="line-20"></a><span class='hs-definition'>string_txt</span> <span class='hs-layout'>(</span><span class='hs-conid'>PStr</span> <span class='hs-varid'>s1</span><span class='hs-layout'>)</span> <span class='hs-varid'>s2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unpackFS</span> <span class='hs-varid'>s1</span> <span class='hs-varop'>++</span> <span class='hs-varid'>s2</span>
<a name="line-21"></a><span class='hs-definition'>string_txt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LStr</span> <span class='hs-varid'>s1</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-varid'>s2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unpackLitString</span> <span class='hs-varid'>s1</span> <span class='hs-varop'>++</span> <span class='hs-varid'>s2</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a>
<a name="line-2"></a><a name="fullRender"></a><span class='hs-definition'>fullRender</span> <span class='hs-conid'>OneLineMode</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>txt</span> <span class='hs-varid'>end</span> <span class='hs-varid'>doc</span>
<a name="line-3"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>doc</span><span class='hs-layout'>)</span>
<a name="line-4"></a>  <span class='hs-keyword'>where</span>
<a name="line-5"></a>    <span class='hs-varid'>lay</span> <span class='hs-conid'>NoDoc</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cant_fail</span>
<a name="line-6"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>Union</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>q</span> <span class='hs-comment'>-- Second arg can't be NoDoc</span>
<a name="line-7"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>p</span>
<a name="line-8"></a>    <span class='hs-varid'>lay</span> <span class='hs-conid'>Empty</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>end</span>
<a name="line-9"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>space_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>p</span> <span class='hs-comment'>-- NoDoc always on</span>
<a name="line-10"></a>                                                    <span class='hs-comment'>-- first line</span>
<a name="line-11"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>p</span>
<a name="line-12"></a>    <span class='hs-varid'>lay</span> <span class='hs-keyword'>_</span>                  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"fullRender/OneLineMode/lay: Unhandled case"</span>
<a name="line-13"></a>
<a name="line-14"></a><span class='hs-definition'>fullRender</span> <span class='hs-conid'>LeftMode</span>    <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>txt</span> <span class='hs-varid'>end</span> <span class='hs-varid'>doc</span>
<a name="line-15"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>doc</span><span class='hs-layout'>)</span>
<a name="line-16"></a>  <span class='hs-keyword'>where</span>
<a name="line-17"></a>    <span class='hs-varid'>lay</span> <span class='hs-conid'>NoDoc</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cant_fail</span>
<a name="line-18"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>Union</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-varid'>first</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-19"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>p</span>
<a name="line-20"></a>    <span class='hs-varid'>lay</span> <span class='hs-conid'>Empty</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>end</span>
<a name="line-21"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nl_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>p</span> <span class='hs-comment'>-- NoDoc always on first line</span>
<a name="line-22"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>p</span>
<a name="line-23"></a>    <span class='hs-varid'>lay</span> <span class='hs-keyword'>_</span>                  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"fullRender/LeftMode/lay: Unhandled case"</span>
<a name="line-24"></a>
<a name="line-25"></a><span class='hs-definition'>fullRender</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>line_length</span> <span class='hs-varid'>ribbons_per_line</span> <span class='hs-varid'>txt</span> <span class='hs-varid'>end</span> <span class='hs-varid'>doc</span>
<a name="line-26"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>display</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>line_length</span> <span class='hs-varid'>ribbon_length</span> <span class='hs-varid'>txt</span> <span class='hs-varid'>end</span> <span class='hs-varid'>best_doc</span>
<a name="line-27"></a>  <span class='hs-keyword'>where</span>
<a name="line-28"></a>    <span class='hs-varid'>best_doc</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>best</span> <span class='hs-varid'>hacked_line_length</span> <span class='hs-varid'>ribbon_length</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>doc</span><span class='hs-layout'>)</span>
<a name="line-29"></a>
<a name="line-30"></a>    <span class='hs-varid'>hacked_line_length</span><span class='hs-layout'>,</span> <span class='hs-varid'>ribbon_length</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
<a name="line-31"></a>    <span class='hs-varid'>ribbon_length</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>round</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>line_length</span> <span class='hs-varop'>/</span> <span class='hs-varid'>ribbons_per_line</span><span class='hs-layout'>)</span>
<a name="line-32"></a>    <span class='hs-varid'>hacked_line_length</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>mode</span> <span class='hs-keyword'>of</span>
<a name="line-33"></a>                         <span class='hs-conid'>ZigZagMode</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>maxBound</span>
<a name="line-34"></a>                         <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>line_length</span>
<a name="line-35"></a>
<a name="line-36"></a><a name="display"></a><span class='hs-definition'>display</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Mode</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextDetails</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>t</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>t</span>
<a name="line-37"></a><span class='hs-definition'>display</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>page_width</span> <span class='hs-varid'>ribbon_width</span> <span class='hs-varid'>txt</span> <span class='hs-varid'>end</span> <span class='hs-varid'>doc</span>
<a name="line-38"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>iUnbox</span> <span class='hs-varid'>page_width</span><span class='hs-layout'>)</span> <span class='hs-varop'>-#</span> <span class='hs-layout'>(</span><span class='hs-varid'>iUnbox</span> <span class='hs-varid'>ribbon_width</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-varid'>gap_width</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-39"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>gap_width</span> <span class='hs-varop'>`quotFastInt`</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>2</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-varid'>shift</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-40"></a>    <span class='hs-keyword'>let</span>
<a name="line-41"></a>        <span class='hs-varid'>lay</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-varid'>k1</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>+#</span> <span class='hs-varid'>k1</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span>
<a name="line-42"></a>        <span class='hs-varid'>lay</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Empty</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>end</span>
<a name="line-43"></a>
<a name="line-44"></a>        <span class='hs-varid'>lay</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nl_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span>
<a name="line-45"></a>
<a name="line-46"></a>        <span class='hs-varid'>lay</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-47"></a>            <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>mode</span> <span class='hs-keyword'>of</span>
<a name="line-48"></a>                    <span class='hs-conid'>ZigZagMode</span> <span class='hs-keyglyph'>|</span>  <span class='hs-varid'>k</span> <span class='hs-varop'>&gt;=#</span> <span class='hs-varid'>gap_width</span>
<a name="line-49"></a>                               <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>nl_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-layout'>(</span>
<a name="line-50"></a>                                  <span class='hs-conid'>Str</span> <span class='hs-layout'>(</span><span class='hs-varid'>multi_ch</span> <span class='hs-varid'>shift</span> <span class='hs-chr'>'/'</span><span class='hs-layout'>)</span> <span class='hs-varop'>`txt`</span> <span class='hs-layout'>(</span>
<a name="line-51"></a>                                  <span class='hs-varid'>nl_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-layout'>(</span>
<a name="line-52"></a>                                  <span class='hs-varid'>lay1</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>-#</span> <span class='hs-varid'>shift</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-53"></a>
<a name="line-54"></a>                               <span class='hs-keyglyph'>|</span>  <span class='hs-varid'>k</span> <span class='hs-varop'>&lt;#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span>
<a name="line-55"></a>                               <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>nl_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-layout'>(</span>
<a name="line-56"></a>                                  <span class='hs-conid'>Str</span> <span class='hs-layout'>(</span><span class='hs-varid'>multi_ch</span> <span class='hs-varid'>shift</span> <span class='hs-chr'>'\\'</span><span class='hs-layout'>)</span> <span class='hs-varop'>`txt`</span> <span class='hs-layout'>(</span>
<a name="line-57"></a>                                  <span class='hs-varid'>nl_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-layout'>(</span>
<a name="line-58"></a>                                  <span class='hs-varid'>lay1</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>+#</span> <span class='hs-varid'>shift</span><span class='hs-layout'>)</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span> <span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-59"></a>
<a name="line-60"></a>                    <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>lay1</span> <span class='hs-varid'>k</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span>
<a name="line-61"></a>        <span class='hs-varid'>lay</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>            <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"display/lay: Unhandled case"</span>
<a name="line-62"></a>
<a name="line-63"></a>        <span class='hs-varid'>lay1</span> <span class='hs-varid'>k</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>indent</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>lay2</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>+#</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-64"></a>
<a name="line-65"></a>        <span class='hs-varid'>lay2</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nl_text</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>lay</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span>
<a name="line-66"></a>        <span class='hs-varid'>lay2</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-varid'>sl</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-varop'>`txt`</span> <span class='hs-layout'>(</span><span class='hs-varid'>lay2</span> <span class='hs-layout'>(</span><span class='hs-varid'>k</span> <span class='hs-varop'>+#</span> <span class='hs-varid'>sl</span><span class='hs-layout'>)</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>
<a name="line-67"></a>        <span class='hs-varid'>lay2</span> <span class='hs-varid'>k</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>          <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lay2</span> <span class='hs-varid'>k</span> <span class='hs-varid'>p</span>
<a name="line-68"></a>        <span class='hs-varid'>lay2</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>Empty</span>               <span class='hs-keyglyph'>=</span> <span class='hs-varid'>end</span>
<a name="line-69"></a>        <span class='hs-varid'>lay2</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"display/lay2: Unhandled case"</span>
<a name="line-70"></a>
<a name="line-71"></a>        <span class='hs-comment'>-- optimise long indentations using LitString chunks of 8 spaces</span>
<a name="line-72"></a>        <span class='hs-varid'>indent</span> <span class='hs-varid'>n</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&gt;=#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>8</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LStr</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>"        "</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>8</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varop'>`txt`</span>
<a name="line-73"></a>                                      <span class='hs-varid'>indent</span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span> <span class='hs-varop'>-#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>8</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>r</span>
<a name="line-74"></a>                   <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Str</span> <span class='hs-layout'>(</span><span class='hs-varid'>spaces</span> <span class='hs-varid'>n</span><span class='hs-layout'>)</span> <span class='hs-varop'>`txt`</span> <span class='hs-varid'>r</span>
<a name="line-75"></a>    <span class='hs-keyword'>in</span>
<a name="line-76"></a>    <span class='hs-varid'>lay</span> <span class='hs-layout'>(</span><span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>doc</span>
<a name="line-77"></a>    <span class='hs-layout'>}</span><span class='hs-layout'>}</span>
<a name="line-78"></a>
<a name="line-79"></a><a name="cant_fail"></a><span class='hs-definition'>cant_fail</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>a</span>
<a name="line-80"></a><span class='hs-definition'>cant_fail</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>error</span> <span class='hs-str'>"easy_display: NoDoc"</span>
<a name="line-81"></a>
<a name="line-82"></a><a name="multi_ch"></a><span class='hs-definition'>multi_ch</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span><span class='hs-cpp'>#</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Char</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-83"></a><span class='hs-definition'>multi_ch</span> <span class='hs-varid'>n</span> <span class='hs-varid'>ch</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&lt;=#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>""</span>
<a name="line-84"></a>              <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>      <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ch</span> <span class='hs-conop'>:</span> <span class='hs-varid'>multi_ch</span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span> <span class='hs-varop'>-#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>ch</span>
<a name="line-85"></a>
<a name="line-86"></a><a name="spaces"></a><span class='hs-definition'>spaces</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span><span class='hs-cpp'>#</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-87"></a><span class='hs-definition'>spaces</span> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&lt;=#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>""</span>
<a name="line-88"></a>         <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>      <span class='hs-keyglyph'>=</span> <span class='hs-chr'>' '</span> <span class='hs-conop'>:</span> <span class='hs-varid'>spaces</span> <span class='hs-layout'>(</span><span class='hs-varid'>n</span> <span class='hs-varop'>-#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>1</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-89"></a>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="pprCols"></a><span class='hs-definition'>pprCols</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
<a name="line-2"></a><span class='hs-definition'>pprCols</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>100</span> <span class='hs-comment'>-- could make configurable</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="printDoc"></a><span class='hs-definition'>printDoc</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Mode</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Handle</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
<a name="line-5"></a><span class='hs-definition'>printDoc</span> <span class='hs-conid'>LeftMode</span> <span class='hs-varid'>hdl</span> <span class='hs-varid'>doc</span>
<a name="line-6"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>{</span> <span class='hs-varid'>printLeftRender</span> <span class='hs-varid'>hdl</span> <span class='hs-varid'>doc</span><span class='hs-layout'>;</span> <span class='hs-varid'>hFlush</span> <span class='hs-varid'>hdl</span> <span class='hs-layout'>}</span>
<a name="line-7"></a><span class='hs-definition'>printDoc</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>hdl</span> <span class='hs-varid'>doc</span>
<a name="line-8"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>{</span> <span class='hs-varid'>fullRender</span> <span class='hs-varid'>mode</span> <span class='hs-varid'>pprCols</span> <span class='hs-num'>1.5</span> <span class='hs-varid'>put</span> <span class='hs-varid'>done</span> <span class='hs-varid'>doc</span> <span class='hs-layout'>;</span>
<a name="line-9"></a>         <span class='hs-varid'>hFlush</span> <span class='hs-varid'>hdl</span> <span class='hs-layout'>}</span>
<a name="line-10"></a>  <span class='hs-keyword'>where</span>
<a name="line-11"></a>    <span class='hs-varid'>put</span> <span class='hs-layout'>(</span><span class='hs-conid'>Chr</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>  <span class='hs-varid'>next</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hPutChar</span> <span class='hs-varid'>hdl</span> <span class='hs-varid'>c</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>next</span>
<a name="line-12"></a>    <span class='hs-varid'>put</span> <span class='hs-layout'>(</span><span class='hs-conid'>Str</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>  <span class='hs-varid'>next</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hPutStr</span>  <span class='hs-varid'>hdl</span> <span class='hs-varid'>s</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>next</span>
<a name="line-13"></a>    <span class='hs-varid'>put</span> <span class='hs-layout'>(</span><span class='hs-conid'>PStr</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-varid'>next</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hPutStr</span>  <span class='hs-varid'>hdl</span> <span class='hs-layout'>(</span><span class='hs-varid'>unpackFS</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>next</span>
<a name="line-14"></a>                        <span class='hs-comment'>-- NB. not hPutFS, we want this to go through</span>
<a name="line-15"></a>                        <span class='hs-comment'>-- the I/O library's encoding layer. (#3398)</span>
<a name="line-16"></a>    <span class='hs-varid'>put</span> <span class='hs-layout'>(</span><span class='hs-conid'>LStr</span> <span class='hs-varid'>s</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-varid'>next</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hPutLitString</span> <span class='hs-varid'>hdl</span> <span class='hs-varid'>s</span> <span class='hs-varid'>l</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>next</span>
<a name="line-17"></a>
<a name="line-18"></a>    <span class='hs-varid'>done</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hPutChar</span> <span class='hs-varid'>hdl</span> <span class='hs-chr'>'\n'</span>
<a name="line-19"></a>
<a name="line-20"></a>  <span class='hs-comment'>-- some versions of hPutBuf will barf if the length is zero</span>
<a name="line-21"></a><a name="hPutLitString"></a><span class='hs-definition'>hPutLitString</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Handle</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Ptr</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span><span class='hs-cpp'>#</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
<a name="line-22"></a><span class='hs-definition'>hPutLitString</span> <span class='hs-varid'>handle</span> <span class='hs-varid'>a</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>l</span> <span class='hs-varop'>==#</span> <span class='hs-sel'>_ILIT</span><span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>)</span>
<a name="line-23"></a>                            <span class='hs-keyword'>then</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-24"></a>                            <span class='hs-keyword'>else</span> <span class='hs-varid'>hPutBuf</span> <span class='hs-varid'>handle</span> <span class='hs-varid'>a</span> <span class='hs-layout'>(</span><span class='hs-varid'>iBox</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span>
<a name="line-25"></a>
<a name="line-26"></a><span class='hs-comment'>-- Printing output in LeftMode is performance critical: it's used when</span>
<a name="line-27"></a><span class='hs-comment'>-- dumping C and assembly output, so we allow ourselves a few dirty</span>
<a name="line-28"></a><span class='hs-comment'>-- hacks:</span>
<a name="line-29"></a><span class='hs-comment'>--</span>
<a name="line-30"></a><span class='hs-comment'>-- (1) we specialise fullRender for LeftMode with IO output.</span>
<a name="line-31"></a><span class='hs-comment'>--</span>
<a name="line-32"></a><span class='hs-comment'>-- (2) we add a layer of buffering on top of Handles.  Handles</span>
<a name="line-33"></a><span class='hs-comment'>--     don't perform well with lots of hPutChars, which is mostly</span>
<a name="line-34"></a><span class='hs-comment'>--     what we're doing here, because Handles have to be thread-safe</span>
<a name="line-35"></a><span class='hs-comment'>--     and async exception-safe.  We only have a single thread and don't</span>
<a name="line-36"></a><span class='hs-comment'>--     care about exceptions, so we add a layer of fast buffering</span>
<a name="line-37"></a><span class='hs-comment'>--     over the Handle interface.</span>
<a name="line-38"></a><span class='hs-comment'>--</span>
<a name="line-39"></a><span class='hs-comment'>-- (3) a few hacks in layLeft below to convince GHC to generate the right</span>
<a name="line-40"></a><span class='hs-comment'>--     code.</span>
<a name="line-41"></a>
<a name="line-42"></a><a name="printLeftRender"></a><span class='hs-definition'>printLeftRender</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Handle</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
<a name="line-43"></a><span class='hs-definition'>printLeftRender</span> <span class='hs-varid'>hdl</span> <span class='hs-varid'>doc</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-44"></a>  <span class='hs-varid'>b</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newBufHandle</span> <span class='hs-varid'>hdl</span>
<a name="line-45"></a>  <span class='hs-varid'>bufLeftRender</span> <span class='hs-varid'>b</span> <span class='hs-varid'>doc</span>
<a name="line-46"></a>  <span class='hs-varid'>bFlush</span> <span class='hs-varid'>b</span>
<a name="line-47"></a>
<a name="line-48"></a><a name="bufLeftRender"></a><span class='hs-definition'>bufLeftRender</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>BufHandle</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
<a name="line-49"></a><span class='hs-definition'>bufLeftRender</span> <span class='hs-varid'>b</span> <span class='hs-varid'>doc</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-varid'>reduceDoc</span> <span class='hs-varid'>doc</span><span class='hs-layout'>)</span>
<a name="line-50"></a>
<a name="line-51"></a><a name="layLeft"></a><span class='hs-comment'>-- HACK ALERT!  the "return () &gt;&gt;" below convinces GHC to eta-expand</span>
<a name="line-52"></a><span class='hs-comment'>-- this function with the IO state lambda.  Otherwise we end up with</span>
<a name="line-53"></a><span class='hs-comment'>-- closures in all the case branches.</span>
<a name="line-54"></a><span class='hs-definition'>layLeft</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>BufHandle</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Doc</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span>
<a name="line-55"></a><span class='hs-definition'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-conid'>False</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span> <span class='hs-comment'>-- make it strict in b</span>
<a name="line-56"></a><span class='hs-definition'>layLeft</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>NoDoc</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cant_fail</span>
<a name="line-57"></a><span class='hs-definition'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>Union</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-varid'>first</span> <span class='hs-varid'>p</span> <span class='hs-varid'>q</span><span class='hs-layout'>)</span>
<a name="line-58"></a><span class='hs-definition'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>Nest</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>         <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-varid'>p</span>
<a name="line-59"></a><span class='hs-definition'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-conid'>Empty</span>              <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bPutChar</span> <span class='hs-varid'>b</span> <span class='hs-chr'>'\n'</span>
<a name="line-60"></a><span class='hs-definition'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>NilAbove</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bPutChar</span> <span class='hs-varid'>b</span> <span class='hs-chr'>'\n'</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-varid'>p</span>
<a name="line-61"></a><span class='hs-definition'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>TextBeside</span> <span class='hs-varid'>s</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>p</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>put</span> <span class='hs-varid'>b</span> <span class='hs-varid'>s</span> <span class='hs-varop'>&gt;&gt;</span> <span class='hs-varid'>layLeft</span> <span class='hs-varid'>b</span> <span class='hs-varid'>p</span>
<a name="line-62"></a> <span class='hs-keyword'>where</span>
<a name="line-63"></a>    <span class='hs-varid'>put</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>b</span> <span class='hs-varop'>`seq`</span> <span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>undefined</span>
<a name="line-64"></a>    <span class='hs-varid'>put</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>Chr</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bPutChar</span> <span class='hs-varid'>b</span> <span class='hs-varid'>c</span>
<a name="line-65"></a>    <span class='hs-varid'>put</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>Str</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bPutStr</span>  <span class='hs-varid'>b</span> <span class='hs-varid'>s</span>
<a name="line-66"></a>    <span class='hs-varid'>put</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>PStr</span> <span class='hs-varid'>s</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bPutFS</span>   <span class='hs-varid'>b</span> <span class='hs-varid'>s</span>
<a name="line-67"></a>    <span class='hs-varid'>put</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-conid'>LStr</span> <span class='hs-varid'>s</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>bPutLitString</span> <span class='hs-varid'>b</span> <span class='hs-varid'>s</span> <span class='hs-varid'>l</span>
<a name="line-68"></a><span class='hs-definition'>layLeft</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"layLeft: Unhandled case"</span>
</pre>\end{code}
</body>
</html>