Skip to content

Commit 99553dc

Browse files
committed
Take 2 + property test
1 parent 83d7471 commit 99553dc

2 files changed

Lines changed: 106 additions & 2 deletions

File tree

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

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,16 +514,106 @@ softline' = group line'
514514
hardline :: Doc ann
515515
hardline = Line
516516

517+
group :: Doc ann -> Doc ann
518+
group = \doc -> case doc of
519+
FlatAlt x y -> case changesOnFlattening x of
520+
HasLine -> y
521+
NoChange -> Union y x
522+
Flat y' -> Union y' x
523+
524+
x@(Cat a b) -> case (changesOnFlattening a, changesOnFlattening b) of
525+
(HasLine , _ ) -> x
526+
(_ , HasLine ) -> x
527+
(NoChange , NoChange) -> x
528+
(NoChange , Flat b' ) -> Cat a (Union b' b)
529+
(Flat a' , NoChange) -> Cat (Union a' a) b
530+
(Flat a' , Flat b' ) -> Union (Cat a' b') (Cat a b)
531+
532+
Annotated ann x -> Annotated ann (group x)
533+
Nest i x -> Nest i (group x)
534+
535+
Column f -> Column (group . f)
536+
Nesting f -> Nesting (group . f)
537+
WithPageWidth f -> WithPageWidth (group . f)
538+
539+
x@Union{} -> x
540+
x@Char{} -> x
541+
x@Text{} -> x
542+
x@Line -> x
543+
x@Empty -> x
544+
-- Should never happen on a valid document
545+
x@Fail -> x
546+
547+
changesOnFlattening :: Doc ann -> FlatteningResult (Doc ann)
548+
changesOnFlattening = \doc -> case doc of
549+
FlatAlt _ y -> case changesOnFlattening y of
550+
HasLine -> HasLine
551+
NoChange -> Flat y
552+
Flat y' -> Flat y'
553+
554+
Union x _ -> Flat x
555+
556+
Cat a b -> case (changesOnFlattening a, changesOnFlattening b) of
557+
(HasLine , _ ) -> HasLine
558+
(_ , HasLine ) -> HasLine
559+
(NoChange , NoChange) -> NoChange
560+
(Flat a' , NoChange) -> Flat (Cat a' b)
561+
(NoChange , Flat b' ) -> Flat (Cat a b')
562+
(Flat a' , Flat b' ) -> Flat (Cat a' b')
563+
564+
Annotated ann x -> Annotated ann <$> (changesOnFlattening x)
565+
Nest i x -> Nest i <$> (changesOnFlattening x)
566+
567+
Column f -> Flat (Column (flatten . f))
568+
Nesting f -> Flat (Nesting (flatten . f))
569+
WithPageWidth f -> Flat (WithPageWidth (flatten . f))
570+
571+
Line -> HasLine
572+
573+
-- Should actually be impossible here. HasLine has the same effect tho
574+
Fail -> HasLine
575+
576+
Text{} -> NoChange
577+
Char{} -> NoChange
578+
Empty -> NoChange
579+
where
580+
flatten :: Doc ann -> Doc ann
581+
flatten = \doc -> case doc of
582+
FlatAlt _ y -> flatten y
583+
Cat x y -> Cat (flatten x) (flatten y)
584+
Nest i x -> Nest i (flatten x)
585+
Line -> Fail
586+
Union x _ -> flatten x
587+
Column f -> Column (flatten . f)
588+
WithPageWidth f -> WithPageWidth (flatten . f)
589+
Nesting f -> Nesting (flatten . f)
590+
Annotated ann x -> Annotated ann (flatten x)
591+
592+
x@Fail -> x
593+
x@Empty -> x
594+
x@Char{} -> x
595+
x@Text{} -> x
596+
597+
data FlatteningResult a
598+
= HasLine
599+
| NoChange
600+
| Flat a
601+
602+
instance Functor FlatteningResult where
603+
fmap _ HasLine = HasLine
604+
fmap _ NoChange = NoChange
605+
fmap f (Flat a) = Flat (f a)
606+
517607
-- | @('group' x)@ tries laying out @x@ into a single line by removing the
518608
-- contained line breaks; if this does not fit the page, @x@ is laid out without
519609
-- any changes. The 'group' function is key to layouts that adapt to available
520610
-- space nicely.
521611
--
522612
-- See 'vcat', 'line', or 'flatAlt' for examples that are related, or make good
523613
-- use of it.
524-
group :: Doc ann -> Doc ann
614+
simpleGroup :: Doc ann -> Doc ann
525615
-- See note [Group: special flattening]
526-
group x = case changesUponFlattening x of
616+
simpleGroup x = case changesUponFlattening x of
527617
Flattened x' -> Union x' x
528618
AlreadyFlat -> x
529619
NeverFlat -> x

prettyprinter/test/Testsuite/Main.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ tests = testGroup "Tests"
9090
, testCase "Line within align" regressionUnboundedGroupedLineWithinAlign
9191
]
9292
]
93+
, testGroup "Group" [
94+
testProperty "simpleGroup == group" groupLayoutEqualsSimpleGroupLayout
95+
]
9396
]
9497

9598
fusionDoesNotChangeRendering :: FusionDepth -> Property
@@ -111,6 +114,17 @@ fusionDoesNotChangeRendering depth
111114
, "Fused:"
112115
, indent 4 (pretty renderedFused) ]
113116

117+
groupLayoutEqualsSimpleGroupLayout :: Property
118+
groupLayoutEqualsSimpleGroupLayout = forAllShow (arbitrary :: Gen (Doc Int)) (show . diag) (\doc ->
119+
forAll arbitrary (\layouter ->
120+
let grouped = group $ doc
121+
groupedSimple = simpleGroup doc
122+
groupedLayedOut = layout layouter grouped
123+
groupedSimpleLayedOut = layout layouter groupedSimple
124+
in counterexample ("Grouped: " ++ (show . diag $ grouped))
125+
(counterexample ("Grouped (Simple) " ++ (show . diag $ groupedSimple))
126+
(groupedLayedOut === groupedSimpleLayedOut))))
127+
114128
instance Arbitrary ann => Arbitrary (Doc ann) where
115129
arbitrary = document
116130
shrink = genericShrink -- Possibly not a good idea, may break invariants

0 commit comments

Comments
 (0)