Home > Net >  Pretty printing in Haskell: Break outer groups when printing nested tuples
Pretty printing in Haskell: Break outer groups when printing nested tuples

Time:08-26

I want to pretty print an AST using Haskell and (currently) wl-pprint-annotated (willing to switch to a different library).

How can I make the renderer prefer breaking the softlines of the outer group over the softlines of the inner group?

Minimal Example

Take for example the tuple ((1234, 5678), (abcd, efgh)).

The output I want:

// line width: 10
(
  (
    1234,
    5678
  ),
  (
    abcd,
    efgh
  )
)

// line width: 16
(
  (1234, 5678),
  (abcd, efgh)
)

// line width: 32
((1234, 5678), (abcd, efgh))

The output I get:

// line width: 10
((1234,
    5678),
  (abcd,
    efgh))

// line width: 16
((1234, 5678), (
    abcd, efgh))

// line width: 32
((1234, 5678), (abcd, efgh))

Code:

module Main where
import qualified Prelude
import Prelude hiding((<>))

import Text.PrettyPrint.Annotated.WL 

main :: IO ()
main = do
  putStrLn $ pp 10
  putStrLn $ pp 16
  putStrLn $ pp 32

pp w = "// line width: "    show w    "\n"   
       display (renderPretty 1.0 w doc)    "\n"

doc = pair (pair (text "1234") (text "5678"))
           (pair (text "abcd") (text "efgh"))

pair x y = group (nest 2 (lparen <//> x <> comma </> y) <//> rparen)

CodePudding user response:

pair x y = group (nest 2 (lparen <##> x <> comma <#> y) <##> rparen)

CodePudding user response:

As ekim found out, I've mixed up </> with <#>

I found the documentation to be confusing, so let me clear it up a little.

First of all the operators </> and <#> are just sugar for line and softline. See definitions:

x </> y = x <> softline <> y
x <#> y = x <> line <> y

Commonalities between line and softline

Both are printed as space when the whole line fits the page. Both are replaced with a line break when the line does not fit the page.

Difference between line and softline

When a group foes not fit the page, all lines of the whole group are replaced with line breaks. That's the behavior I've wanted.

When the line does not fit the page, only the last softline still fitting the page is replaced. Not the whole group. It's like the word wrapping in our text editors: Just breaking after the last word that fits to the page.

For example

doc = paragraph p1
paragraph = foldr (</>) mempty . map text . words
p1 = "I want to pretty print an AST using Haskell and (currently) wl-pprint-annotated (willing to switch to a different library)."

is printed as

I want to pretty print an AST using Haskell and
(currently) wl-pprint-annotated (willing to
switch to a different library).
  • Related