#669: negative indentation in Text.PrettyPrint.HughesPJ
------------------------------------------+---------------------------------
Reporter: [EMAIL PROTECTED] | Owner: thorkilnaur
Type: bug | Status: new
Priority: normal | Milestone: 6.8
Component: hslibs/text | Version: 6.4.1
Severity: minor | Resolution:
Keywords: | Difficulty: Unknown
Testcase: pp1 | Architecture: Unknown
Os: Unknown |
------------------------------------------+---------------------------------
Comment (by thorkilnaur):
This problem is also present in the original Hughes library
http://www.cs.chalmers.se/~rjmh/Software/NewPP.hs. An example is
{{{
$ ghc -e 'putStr $ pretty 2 2 $ text "a" <> sep [ nest 4 (text "b"), text
"c" ]' NewPP
ab
c
$
}}}
where the c should have been printed below the b and not below the a.
Instrumenting slightly
{{{
$ diff Newpp.hs Newpp2.hs
99c99
< layout k x = [' ' | i<-[1..k]] ++ layout' k x
---
> layout k x = "<" ++ show k ++ ">" ++ layout' k x
$ ghc -e 'putStr $ pretty 2 2 $ text "a" <> sep [ nest 4 (text "b"), text
"c" ]' NewPP2
<0>ab
<-3>c
$
}}}
we can observe that the pretty-printer actually intends to print the c 3
positions to the left of the left margin.
The problem can be traced further back in the paper "The Design of a
Pretty-printing Library" by John Hughes
(http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps) where the original
pretty-printing library is developed: Using the law
{{{
x <> nest k y = x <> y
}}}
from section "7.2 The Algebra of Layouts" and the relation
{{{
sep (nest k x : xs) = nest k (sep (x : map (nest (-k)) xs ))
}}}
derived in section "8 Implementing Pretty-printing: A Term
Representation", we can derive
{{{
z <> sep (nest k x : xs)
= z <> (nest k (sep (x : map (nest (-k)) xs )))
= z <> (sep (x : map (nest (-k)) xs ))
}}}
which seems problematic in general. There is a clear correspondence
between this relation and the behaviour of the library.
I have worked out a draft repair of the original library: Instead of
sometimes removing nests completely, they are retained in the documents
and simply ignored when required. In this way, the indent amount can be
calculated correctly. Additional adjustmenst are needed to ensure that
line widths remain correctly calculated.
The differences between the original and the repaired library NewPP3.hs
are:
{{{
$ diff NewPP.hs NewPP3.hs
41d40
< Nil <> (Nest k x) = Nil <> x
74c73
< best w r (s `TextBeside` x) = s `TextBeside` best' w r s x
---
> best w r (s `TextBeside` x) = s `TextBeside` best' (w,w) r s x
80c79
< best' w r s (NilAbove x) = NilAbove (best (w-len s) r x)
---
> best' (w1,_) r s (NilAbove x) = NilAbove (best (w1-len s) r x)
83,85c82,84
< best' w r s (Nest k x) = best' w r s x
< best' w r s (x `Union` y) =
< nicest' w r s (best' w r s x) (best' w r s y)
---
> best' (w1,w2) r s (Nest k x) = Nest k (best' (w1-k,w2) r s x)
> best' w@(_,w2) r s (x `Union` y) =
> nicest' w2 r s (best' w r s x) (best' w r s y)
95a95
> Nest k' y -> fits n k y
103a104
> layout' k (Nest k' x) = layout' (k+k') x
$
}}}
NewPP3.hs is attached.
A similar repair can be carried out for the HughesPJ library. A patch for
this draft change (HughesPJIndentRepair.patch) is attached. In addition, a
patch for the pp1 test case (pp1IndentRepair.patch) is attached.
Please note that I have not carried out an exhaustive test of the repaired
HughesPJ library. For example, with nests now being retained more often in
the documents, there could well be cases left in the library where a nest
will cause a pattern match failure. Besides pp1, I have not been able to
find test material related to the HughesPJ library. I would be most
interested to hear about such material.
Thorkil
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/669>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs