[More progress on the Prettify library. Bryan O'Sullivan **20080226070851] { hunk ./en/ch06-library.xml 353 - functions would be part of our generic library. If we don't - provide definitions for those functions, our attempts to - compile early, compile often with our JSON - renderer will fail, as the compiler won't know anything about - those functions. To avoid this problem, we write stub functions - that don't do anything. + functions would be provided by our Prettify module. + If we don't provide definitions for those functions, our + attempts to compile early, compile often with our + JSON renderer will fail, as the compiler won't know anything + about those functions. To avoid this problem, we write stub + functions that don't do anything. hunk ./en/ch06-library.xml 584 - our generic pretty printing library. It combines a series of + our Prettify module. It combines a series of hunk ./en/ch06-library.xml 586 - output will not fit on a single line. + output will not fit on a single line. The + punctuate function will also live in our + Prettify module, and we can define it in terms of + functions for which we've already written stubs. + + &Prettify.hs:punctuate; hunk ./en/ch06-library.xml 671 + + + Fleshing out the pretty printing library + + In our Prettify module, we represent our + Doc type as an algebraic data type. + + &Prettify.hs:Doc; + + In the header of our module, we will export the name of the + type, but not any of its constructors: this will prevent modules + that use the Doc type from creating and pattern + matching against Doc values. + + Instead, to create a Doc, a user of the + Prettify module will call a function that we + provide. Here are the simple construction functions. + + &Prettify.hs:basic; + + The Line constructor represents a line break. + It takes a parameter of type Bool, to indicate + whether a line break is mandatory (a hard break), + or only needed if a line might otherwise become too wide (a + soft break). The line + function only creates hard line breaks; we'll introduce a + softline function shortly. + + &Prettify.hs:line; + + Almost as simple as the basic constructors is the + (<>) function, which concatenates two + Doc values. + + &Prettify.hs:append; + + Notice that we pattern match against Empty: + concatenating a Doc value with Empty + on the left or right has no effect. If we briefly put on our + mathematical hats, we can say that Empty is the + identity under concatenation. Taking the mathematical + perspective has useful practical consequences, and we'll explain + why later. + + Add a reference to wherever we introduce monoids. + + + hunk ./examples/ch06/Prettify.hs 12 - , (<+>) hunk ./examples/ch06/Prettify.hs 23 +{-- snippet Doc --} hunk ./examples/ch06/Prettify.hs 30 +{-- /snippet Doc --} hunk ./examples/ch06/Prettify.hs 36 +{-- snippet append --} hunk ./examples/ch06/Prettify.hs 38 +Empty <> y = y +x <> Empty = x hunk ./examples/ch06/Prettify.hs 41 +{-- /snippet append --} hunk ./examples/ch06/Prettify.hs 43 +{-- snippet basic --} hunk ./examples/ch06/Prettify.hs 50 -line :: Doc -line = Line False - hunk ./examples/ch06/Prettify.hs 54 +double :: Double -> Doc +double d = text (show d) +{-- /snippet basic --} + +{-- snippet line --} +line :: Doc +line = Line False +{-- /snippet line --} + hunk ./examples/ch06/Prettify.hs 85 +{-- snippet punctuate --} hunk ./examples/ch06/Prettify.hs 90 - -(<+>) :: Doc -> Doc -> Doc -x <+> y = x <> char ' ' <> y - -double :: Double -> Doc -double d = text (show d) +{-- /snippet punctuate --} }