Skip to content

Commit 4ab01d1

Browse files
committed
Rework group and remove fail
1 parent 83d7471 commit 4ab01d1

File tree

11 files changed

+58
-158
lines changed

11 files changed

+58
-158
lines changed

prettyprinter-ansi-terminal/src/Data/Text/Prettyprint/Doc/Render/Terminal/Internal.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ renderLazy sdoc = runST (do
133133
writeOutput x = modifySTRef outputRef (<> x)
134134

135135
let go = \sds -> case sds of
136-
SFail -> panicUncaughtFail
137136
SEmpty -> pure ()
138137
SChar c rest -> do
139138
writeOutput (TLB.singleton c)
@@ -194,7 +193,6 @@ renderIO h sdoc = do
194193
x:xs -> writeIORef styleStackRef xs >> pure x
195194

196195
let go = \sds -> case sds of
197-
SFail -> panicUncaughtFail
198196
SEmpty -> pure ()
199197
SChar c rest -> do
200198
hPutChar h c

prettyprinter-compat-annotated-wl-pprint/src/Text/PrettyPrint/Annotated/Leijen.hs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ displayDecorated decor sd = go id id [] sd ""
119119
in go (sf' . showString formatted) d' stk x
120120
go _ _ [] (SAnnPop _) = error "stack underflow"
121121
go _ _ _ SEmpty = error "stack not consumed by rendering"
122-
go _ _ _ SFail = panicUncaughtFail
123122

124123
displayDecoratedA :: (Applicative f, Monoid b)
125124
=> (String -> f b) -> (a -> f b) -> (a -> f b)
@@ -136,7 +135,6 @@ displayDecoratedA str start end sd = go [] sd
136135
-- malformed documents
137136
go [] (SAnnPop _) = error "stack underflow"
138137
go _ SEmpty = error "stack not consumed by rendering"
139-
go _ SFail = panicUncaughtFail
140138

141139
(<++>) = liftA2 mappend
142140

@@ -157,7 +155,6 @@ displaySpans sd = go 0 [] sd
157155
-- malformed documents
158156
go _ [] (SAnnPop _) = error "stack underflow"
159157
go _ _ SEmpty = error "Stack not consumed by rendering"
160-
go _ _ SFail = panicUncaughtFail
161158

162159
mapFst :: (a -> b) -> (a, c) -> (b, c)
163160
mapFst f (x, y) = (f x, y)
@@ -168,7 +165,6 @@ displaySpans sd = go 0 [] sd
168165
displayIO :: Handle -> SimpleDoc a -> IO ()
169166
displayIO h simpleDoc = go simpleDoc
170167
where
171-
go SFail = panicUncaughtFail
172168
go SEmpty = pure ()
173169
go (SChar c x) = hPutChar h c >> go x
174170
go (SText _ s x) = T.hPutStr h s >> go x

prettyprinter-convert-ansi-wl-pprint/src/Data/Text/Prettyprint/Convert/AnsiWlPprint.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import qualified Text.PrettyPrint.ANSI.Leijen.Internal as Old
3333
-- | @ansi-wl-pprint ───▷ prettyprinter@
3434
fromAnsiWlPprint :: Old.Doc -> New.Doc NewTerm.AnsiStyle
3535
fromAnsiWlPprint = \doc -> case doc of
36-
Old.Fail -> New.Fail
36+
Old.Fail -> undefined -- TODO
3737
Old.Empty -> New.Empty
3838
Old.Char c -> New.Char c
3939
Old.Text l t -> New.Text l (T.pack t)
@@ -86,7 +86,6 @@ fromAnsiWlPprint = \doc -> case doc of
8686
-- | @prettyprinter ───▷ ansi-wl-pprint@
8787
toAnsiWlPprint :: New.Doc NewTerm.AnsiStyle -> Old.Doc
8888
toAnsiWlPprint = \doc -> case doc of
89-
New.Fail -> Old.Fail
9089
New.Empty -> Old.Empty
9190
New.Char c -> Old.Char c
9291
New.Text l t -> Old.Text l (T.unpack t)

prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs

Lines changed: 56 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,8 @@ import Data.Text.Prettyprint.Doc.Render.Util.Panic
8080
-- hello
8181
-- world
8282
data Doc ann =
83-
84-
-- | Occurs when flattening a line. The layouter will reject this document,
85-
-- choosing a more suitable rendering.
86-
Fail
87-
8883
-- | The empty document; conceptually the unit of 'Cat'
89-
| Empty
84+
Empty
9085

9186
-- | invariant: not '\n'
9287
| Char !Char
@@ -523,88 +518,61 @@ hardline = Line
523518
-- use of it.
524519
group :: Doc ann -> Doc ann
525520
-- See note [Group: special flattening]
526-
group x = case changesUponFlattening x of
527-
Flattened x' -> Union x' x
528-
AlreadyFlat -> x
529-
NeverFlat -> x
530-
531-
-- Note [Group: special flattening]
532-
--
533-
-- Since certain documents do not change under removal of newlines etc, there is
534-
-- no point in creating a 'Union' of the flattened and unflattened version – all
535-
-- this does is introducing two branches for the layout algorithm to take,
536-
-- resulting in potentially exponential behavior on deeply nested examples, such
537-
-- as
538-
--
539-
-- pathological n = iterate (\x -> hsep [x, sep []] ) "foobar" !! n
540-
--
541-
-- See https://github.com/quchen/prettyprinter/issues/22 for the corresponding
542-
-- ticket.
543-
544-
data FlattenResult a
545-
= Flattened a
546-
-- ^ @a@ is likely flatter than the input.
547-
| AlreadyFlat
548-
-- ^ The input was already flat, e.g. a 'Text'.
549-
| NeverFlat
550-
-- ^ The input couldn't be flattened: It contained a 'Line' or 'Fail'.
521+
group = \doc -> case doc of
522+
FlatAlt x y -> Union (group y) x
523+
x@(Union _ _) -> x
524+
525+
x@(Cat a b) -> case groupNoLine a of
526+
-- We could not flatten the left side
527+
HasLine -> x
528+
-- Left side flattened without a problem
529+
FlatNoLine a' -> Cat a' (group b)
530+
-- Left side may contain a Line, need to wrap in Union
531+
FlatMaybeLine a' -> Union (Cat a' (group b)) x
532+
533+
Annotated a x -> Annotated a (group x)
534+
Nest i x -> Nest i (group x)
535+
Column f -> Column (group . f)
536+
Nesting f -> Nesting (group . f)
537+
WithPageWidth f -> WithPageWidth (group . f)
538+
539+
x@Text{} -> x
540+
x@Char{} -> x
541+
x@Empty -> x
542+
x@Line -> x
543+
where
544+
groupNoLine :: Doc ann -> FlattenResult (Doc ann)
545+
groupNoLine = \doc -> case doc of
546+
FlatAlt x y -> (flip Union $ x) <$> (groupNoLine y)
547+
Union x _ -> FlatNoLine x
548+
Line -> HasLine
549+
Cat x y -> case (groupNoLine x, groupNoLine y) of
550+
(HasLine , _ ) -> HasLine
551+
(_ , HasLine ) -> HasLine
552+
(FlatMaybeLine a , FlatMaybeLine b) -> FlatMaybeLine (Cat a b)
553+
(FlatMaybeLine a , FlatNoLine b ) -> FlatMaybeLine (Cat a b)
554+
(FlatNoLine a , FlatMaybeLine b) -> FlatMaybeLine (Cat a b)
555+
(FlatNoLine a , FlatNoLine b ) -> FlatNoLine (Cat a b)
556+
557+
Annotated a x -> Annotated a <$> groupNoLine x
558+
Nest i x -> Nest i <$> groupNoLine x
559+
Column f -> FlatMaybeLine (Column (group . f))
560+
Nesting f -> FlatMaybeLine (Nesting (group . f))
561+
WithPageWidth f -> FlatMaybeLine (WithPageWidth (group . f))
562+
563+
x@Text{} -> FlatNoLine x
564+
x@Char{} -> FlatNoLine x
565+
x@Empty -> FlatNoLine x
566+
567+
data FlattenResult a =
568+
FlatNoLine a
569+
| FlatMaybeLine a
570+
| HasLine
551571

552572
instance Functor FlattenResult where
553-
fmap f (Flattened a) = Flattened (f a)
554-
fmap _ AlreadyFlat = AlreadyFlat
555-
fmap _ NeverFlat = NeverFlat
556-
557-
-- | Choose the first element of each @Union@, and discard the first field of
558-
-- all @FlatAlt@s.
559-
--
560-
-- The result is 'Flattened' if the element might change depending on the layout
561-
-- algorithm (i.e. contains differently renderable sub-documents), and 'AlreadyFlat'
562-
-- if the document is static (e.g. contains only a plain 'Empty' node).
563-
-- 'NeverFlat' is returned when the document cannot be flattened because it
564-
-- contains a hard 'Line' or 'Fail'.
565-
-- See [Group: special flattening] for further explanations.
566-
changesUponFlattening :: Doc ann -> FlattenResult (Doc ann)
567-
changesUponFlattening = \doc -> case doc of
568-
FlatAlt _ y -> Flattened (flatten y)
569-
Line -> NeverFlat
570-
Union x _ -> Flattened x
571-
Nest i x -> fmap (Nest i) (changesUponFlattening x)
572-
Annotated ann x -> fmap (Annotated ann) (changesUponFlattening x)
573-
574-
Column f -> Flattened (Column (flatten . f))
575-
Nesting f -> Flattened (Nesting (flatten . f))
576-
WithPageWidth f -> Flattened (WithPageWidth (flatten . f))
577-
578-
Cat x y -> case (changesUponFlattening x, changesUponFlattening y) of
579-
(NeverFlat , _ ) -> NeverFlat
580-
(_ , NeverFlat ) -> NeverFlat
581-
(Flattened x' , Flattened y') -> Flattened (Cat x' y')
582-
(Flattened x' , AlreadyFlat ) -> Flattened (Cat x' y)
583-
(AlreadyFlat , Flattened y') -> Flattened (Cat x y')
584-
(AlreadyFlat , AlreadyFlat ) -> AlreadyFlat
585-
586-
Empty -> AlreadyFlat
587-
Char{} -> AlreadyFlat
588-
Text{} -> AlreadyFlat
589-
Fail -> NeverFlat
590-
where
591-
-- Flatten, but don’t report whether anything changes.
592-
flatten :: Doc ann -> Doc ann
593-
flatten = \doc -> case doc of
594-
FlatAlt _ y -> flatten y
595-
Cat x y -> Cat (flatten x) (flatten y)
596-
Nest i x -> Nest i (flatten x)
597-
Line -> Fail
598-
Union x _ -> flatten x
599-
Column f -> Column (flatten . f)
600-
WithPageWidth f -> WithPageWidth (flatten . f)
601-
Nesting f -> Nesting (flatten . f)
602-
Annotated ann x -> Annotated ann (flatten x)
603-
604-
x@Fail -> x
605-
x@Empty -> x
606-
x@Char{} -> x
607-
x@Text{} -> x
573+
fmap f (FlatNoLine a) = FlatNoLine (f a)
574+
fmap f (FlatMaybeLine a) = FlatMaybeLine (f a)
575+
fmap _ HasLine = HasLine
608576

609577

610578

@@ -1266,7 +1234,6 @@ alterAnnotations :: (ann -> [ann']) -> Doc ann -> Doc ann'
12661234
alterAnnotations re = go
12671235
where
12681236
go = \doc -> case doc of
1269-
Fail -> Fail
12701237
Empty -> Empty
12711238
Char c -> Char c
12721239
Text l t -> Text l t
@@ -1292,7 +1259,6 @@ unAnnotateS :: SimpleDocStream ann -> SimpleDocStream xxx
12921259
unAnnotateS = go
12931260
where
12941261
go = \doc -> case doc of
1295-
SFail -> SFail
12961262
SEmpty -> SEmpty
12971263
SChar c rest -> SChar c (go rest)
12981264
SText l t rest -> SText l t (go rest)
@@ -1305,7 +1271,6 @@ reAnnotateS :: (ann -> ann') -> SimpleDocStream ann -> SimpleDocStream ann'
13051271
reAnnotateS re = go
13061272
where
13071273
go = \doc -> case doc of
1308-
SFail -> SFail
13091274
SEmpty -> SEmpty
13101275
SChar c rest -> SChar c (go rest)
13111276
SText l t rest -> SText l t (go rest)
@@ -1329,7 +1294,6 @@ alterAnnotationsS re = go []
13291294
-- We keep a stack of whether to remove a pop so that we can remove exactly
13301295
-- the pops corresponding to annotations that mapped to Nothing.
13311296
go stack = \sds -> case sds of
1332-
SFail -> SFail
13331297
SEmpty -> SEmpty
13341298
SChar c rest -> SChar c (go stack rest)
13351299
SText l t rest -> SText l t (go stack rest)
@@ -1445,8 +1409,7 @@ fuse depth = go
14451409
-- convert from @'SimpleDocStream'@. The »Render« submodules provide some
14461410
-- built-in converters to do so, and helpers to create own ones.
14471411
data SimpleDocStream ann =
1448-
SFail
1449-
| SEmpty
1412+
SEmpty
14501413
| SChar Char (SimpleDocStream ann)
14511414

14521415
-- | Some layout algorithms use the Since the frequently used 'T.length' of
@@ -1494,7 +1457,6 @@ removeTrailingWhitespace = go (RecordedWhitespace [] 0)
14941457
-- We do not strip whitespace inside annotated documents, since it might
14951458
-- actually be relevant there.
14961459
go annLevel@(AnnotationLevel annLvl) = \sds -> case sds of
1497-
SFail -> SFail
14981460
SEmpty -> SEmpty
14991461
SChar c rest -> SChar c (go annLevel rest)
15001462
SText l text rest -> SText l text (go annLevel rest)
@@ -1508,7 +1470,6 @@ removeTrailingWhitespace = go (RecordedWhitespace [] 0)
15081470
-- Record all spaces/lines encountered, and once proper text starts again,
15091471
-- release only the necessary ones.
15101472
go (RecordedWhitespace withheldLines withheldSpaces) = \sds -> case sds of
1511-
SFail -> SFail
15121473
SEmpty -> foldr (\_i sds' -> SLine 0 sds') SEmpty withheldLines
15131474
SChar c rest
15141475
| c == ' ' -> go (RecordedWhitespace withheldLines (withheldSpaces+1)) rest
@@ -1577,7 +1538,6 @@ instance Foldable SimpleDocStream where
15771538
foldMap f = go
15781539
where
15791540
go = \sds -> case sds of
1580-
SFail -> mempty
15811541
SEmpty -> mempty
15821542
SChar _ rest -> go rest
15831543
SText _ _ rest -> go rest
@@ -1591,7 +1551,6 @@ instance Traversable SimpleDocStream where
15911551
traverse f = go
15921552
where
15931553
go = \sds -> case sds of
1594-
SFail -> pure SFail
15951554
SEmpty -> pure SEmpty
15961555
SChar c rest -> SChar c <$> go rest
15971556
SText l t rest -> SText l t <$> go rest
@@ -1679,7 +1638,6 @@ layoutPretty = layoutWadlerLeijen
16791638
-> SimpleDocStream ann
16801639
-> Bool
16811640
fits w _ | w < 0 = False
1682-
fits _ SFail = False
16831641
fits _ SEmpty = True
16841642
fits w (SChar _ x) = fits (w - 1) x
16851643
fits w (SText l _t x) = fits (w - l) x
@@ -1751,7 +1709,6 @@ layoutSmart = layoutWadlerLeijen (FittingPredicate fits)
17511709
-> SimpleDocStream ann
17521710
-> Bool
17531711
fits _ _ w _ | w < 0 = False
1754-
fits _ _ _ SFail = False
17551712
fits _ _ _ SEmpty = True
17561713
fits pw m w (SChar _ x) = fits pw m (w - 1) x
17571714
fits pw m w (SText l _t x) = fits pw m (w - l) x
@@ -1784,7 +1741,6 @@ layoutWadlerLeijen
17841741
best !_ !_ Nil = SEmpty
17851742
best nl cc (UndoAnn ds) = SAnnPop (best nl cc ds)
17861743
best nl cc (Cons i d ds) = case d of
1787-
Fail -> SFail
17881744
Empty -> best nl cc ds
17891745
Char c -> let !cc' = cc+1 in SChar c (best nl cc' ds)
17901746
Text l t -> let !cc' = cc+l in SText l t (best nl cc' ds)
@@ -1827,41 +1783,9 @@ layoutWadlerLeijen
18271783
ribbonWidth =
18281784
(max 0 . min lineLength . round)
18291785
(fromIntegral lineLength * ribbonFraction)
1830-
Unbounded
1831-
-- See the Note [Detecting failure with Unbounded page width].
1832-
| not (failsOnFirstLine x) -> x
1786+
Unbounded -> x
18331787
_ -> y
18341788

1835-
failsOnFirstLine :: SimpleDocStream ann -> Bool
1836-
failsOnFirstLine = go
1837-
where
1838-
go sds = case sds of
1839-
SFail -> True
1840-
SEmpty -> False
1841-
SChar _ s -> go s
1842-
SText _ _ s -> go s
1843-
SLine _ _ -> False
1844-
SAnnPush _ s -> go s
1845-
SAnnPop s -> go s
1846-
1847-
1848-
-- Note [Detecting failure with Unbounded page width]
1849-
--
1850-
-- To understand why it is sufficient to check the first line of the
1851-
-- SimpleDocStream, trace how an SFail ends up there:
1852-
--
1853-
-- 1. We group a Doc containing a Line, producing a (Union x y) where
1854-
-- x contains Fail.
1855-
--
1856-
-- 2. In best, any Unions are handled recursively, rejecting any
1857-
-- alternatives that would result in SFail.
1858-
--
1859-
-- So once a SimpleDocStream reaches selectNicer, any SFail in it must
1860-
-- appear before the first linebreak – any other SFail would have been
1861-
-- detected and rejected in a previous iteration.
1862-
1863-
1864-
18651789
-- | @(layoutCompact x)@ lays out the document @x@ without adding any
18661790
-- indentation. Since no \'pretty\' printing is involved, this layouter is very
18671791
-- fast. The resulting output contains fewer characters than a prettyprinted
@@ -1885,7 +1809,6 @@ layoutCompact doc = scan 0 [doc]
18851809
where
18861810
scan _ [] = SEmpty
18871811
scan !col (d:ds) = case d of
1888-
Fail -> SFail
18891812
Empty -> scan col ds
18901813
Char c -> SChar c (scan (col+1) ds)
18911814
Text l t -> let !col' = col+l in SText l t (scan col' ds)
@@ -1913,7 +1836,6 @@ instance Show (Doc ann) where
19131836
-- @
19141837
renderShowS :: SimpleDocStream ann -> ShowS
19151838
renderShowS = \sds -> case sds of
1916-
SFail -> panicUncaughtFail
19171839
SEmpty -> id
19181840
SChar c x -> showChar c . renderShowS x
19191841
SText _l t x -> showString (T.unpack t) . renderShowS x

prettyprinter/src/Data/Text/Prettyprint/Doc/Internal/Debug.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ import qualified Data.Text.Prettyprint.Doc.Internal as Doc
3434
-- constructors don't contain functions but are \"sampled\" to allow
3535
-- simple inspection with 'show'.
3636
data Diag ann =
37-
Fail
38-
| Empty
37+
Empty
3938
| Char !Char
4039
| Text !Int !Text
4140
| Line
@@ -76,7 +75,6 @@ diag'
7675
diag' columns pageWidths nestings = go
7776
where
7877
go doc = case doc of
79-
Doc.Fail -> Fail
8078
Doc.Empty -> Empty
8179
Doc.Char c -> Char c
8280
Doc.Text l t -> Text l t

0 commit comments

Comments
 (0)