module Problem2c where import Data.List data Doc = Doc :$$ Doc | Doc :<> Doc | Empty | Text String deriving Show ($$) :: Doc -> Doc -> Doc ($$) = (:$$) empty :: Doc empty = Empty (<>) :: Doc -> Doc -> Doc (<>) = (:<>) text :: String -> Doc text = Text -- Derived combinators indent :: Int -> Doc -> Doc indent n x = text (replicate n ' ') <> x (<+>) :: Doc -> Doc -> Doc x <+> y = x <> indent 1 y -- Run function render :: Doc -> String render = unlines . toLines toLines :: Doc -> [String] toLines (x :$$ y) = toLines x ++ toLines y toLines Empty = [] toLines (Text s) = [s] toLines (x :<> y) = toLines x `hcat` toLines y where -- Same as the shallow implementation of (<>) hcat [] ys = ys hcat xs [] = xs hcat [x] (y : ys) = (x ++ y) : map (replicate (length x) ' ' ++) ys hcat (x : xs) ys = x : hcat xs ys