@@ -514,16 +514,106 @@ softline' = group line'
514514hardline :: Doc ann
515515hardline = 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
0 commit comments