{ {-# LINE 210 "Slides.ltx" #-} class Format a where noDoc :: a text :: String -> a line :: a (<>) :: a -> a -> a group :: a -> a nest :: Int -> a -> a {-# LINE 236 "Slides.ltx" #-} data Tree = Tree String [Tree] {-# LINE 241 "Slides.ltx" #-} ex = Tree "aaa" [Tree "bbbb" [Tree "ccc" [] ,Tree "dd" [] ] ,Tree "eee" [] ,Tree "ffff" [Tree "gg" [] ,Tree "hhh" [] ,Tree "ii" [] ] ] {-# LINE 268 "Slides.ltx" #-} showTree (Tree s ts) = group ( text s <> nest (length s) (showBracket ts) ) showBracket [] = noDoc showBracket ts = text "[" <> nest 1 (showTrees ts) <> text "]" showTrees [t] = showTree t showTrees (t:ts) = showTree t <> text "," <> line <> showTrees ts {-# LINE 324 "Slides.ltx" #-} type Width = Int w :: Width {-# LINE 328 "Slides.ltx" #-} w = 20 {-# LINE 349 "Slides.ltx" #-} type Fit = Bool {-# LINE 351 "Slides.ltx" #-} type Space = Int {-# LINE 353 "Slides.ltx" #-} type Hp = Int {-# LINE 355 "Slides.ltx" #-} type Indent = Int {-# LINE 357 "Slides.ltx" #-} type Formatter1 = Fit -> Space -> Hp -> Indent -> (Space, Hp, Result) {-# LINE 382 "Slides.ltx" #-} type Result = String -> String toSeq s = s [] {-# LINE 655 "Slides.ltx" #-} type FittingChildren1 = Fits -> Fits -- efficient list implementation {-# LINE 657 "Slides.ltx" #-} type Mep = Int {-# LINE 659 "Slides.ltx" #-} data Q = Q Mep FittingChildren1 {-# LINE 661 "Slides.ltx" #-} type Fits = [Bool] type Path = [Q] {-# LINE 671 "Slides.ltx" #-} enterGroup :: Mep -> Path -> Path leaveGroup :: Hp -> ( Path, Fits) -> ( Path, Fits) prune :: Hp -> ( Path, Fits) -> ( Path, Fits) {-# LINE 682 "Slides.ltx" #-} enterGroup mep p = p ++ [Q mep id] {-# LINE 699 "Slides.ltx" #-} leaveGroup hp pa@(p, a) = case p of [] -> pa {-# LINE 703 "Slides.ltx" #-} [Q mep c] -> ([] , (mep<=hp): c a ) {-# LINE 713 "Slides.ltx" #-} pp -> let (Q mep2 c2:(Q mep1 c1:qq)) = reverse pp in ( reverse (Q mep1 (c1.((hp <= mep2):).c2):qq) , a ) {-# LINE 724 "Slides.ltx" #-} prune hp pa@(p,a) = case p of [] -> pa (Q mep c:p') | hp <= mep -> pa | True -> let (p'' , rest ) = prune hp (p', a) in (p'' , False: c rest ) } {-# LINE 903 "Slides.ltx" #-} DATA Doc | NoDoc | Text t:String | Line | Besides l: Doc r: Doc | Group d: Doc | Nest j: Int d: Doc {-# LINE 913 "Slides.ltx" #-} ATTR Doc [|res:String|] {-# LINE 916 "Slides.ltx" #-} SEM Doc | Text lhs.res = @t ++ @lhs.res | Line lhs.res = @lr | Besides r.res = @lhs.res l.res = @r.res lhs.res = @l.res {-# LINE 928 "Slides.ltx" #-} SEM Doc [|h:Int|] | Text lhs.h = @l + @lhs.h loc.l = length @t | Line lhs.h = 1 + @lhs.h {-# LINE 937 "Slides.ltx" #-} SEM Doc [|s:Int|] | Text lhs.s = @lhs.s - @l | Line lhs.s = @lhs.s - @ls loc.(lr, ls) = newLine (head @lhs.f) @lhs.s @lhs.i @lhs.res { newLine True s i rest = ( (' ':rest) , s - 1 ) newLine False s i rest = ((('\n':replicate i ' ')++rest) , w - i ) } {-# LINE 945 "Slides.ltx" #-} SEM Doc [|f:Fits|] | Group d.f = tail (@lhs.f) lhs.f = head @lhs.f:tail @d.f {-# LINE 953 "Slides.ltx" #-} SEM Doc [i: Int||] | Nest d.i = @lhs.i + @j {-# LINE 958 "Slides.ltx" #-} SEM Doc [| future: {[Int]} |] | Text lhs.future = length @t : @lhs.future | Line lhs.future = [] | Besides r.future = @lhs.future l.future = @r.future lhs.future = @l.future {-# LINE 971 "Slides.ltx" #-} ATTR Doc [|p:Path a:Fits|] {-# LINE 977 "Slides.ltx" #-} SEM Doc | Line loc.(p,a) = foldr prune (@lhs.p, @lhs.a) (1: @lhs.future ) {-# LINE 984 "Slides.ltx" #-} | Besides r.a = @lhs.a l.a = @r.a lhs.a = @l.a {-# LINE 993 "Slides.ltx" #-} | Group d.p = enterGroup (@lhs.h + @lhs.s) @lhs.p loc.(p,a) = leaveGroup @d.h (@d.p, @lhs.a) lhs.a = @d.a {-# LINE 1000 "Slides.ltx" #-} DATA Root [||res: String] | Root d:Doc SEM Root | Root d.s = w d.res = [] d.f = False: @d.a d.h = 0 d.i = 0 d.future = [] d.p = [] d.a = []