[Coding style tips. Bryan O'Sullivan **20071026060930] { hunk ./en/book-shortcuts.xml 89 +in"> hunk ./en/ch03-funcs-types.xml 1092 - configuration; this could lead to compilation problems, too. - Using space characters instead avoids this problem + configuration. In fact, this could lead to compilation + problems, as the Haskell language standard requires + implementations to use the Unix tab width convention. + Using space characters avoids these problem hunk ./en/ch09-find-dsl.xml 905 - While much of good programming taste comes from experience, - we have a few general guidelines to offer. + + + + Useful coding guidelines + + While many good Haskell programming habits come with + experience, we have a few general guidelines to offer so that + you can write readable code more quickly. + + As we already mentioned in , never use tab characters + in Haskell source files. Use spaces. + + If you find yourself proudly thinking that a particular + piece of code is fiendishly clever, stop and consider whether + you'll be able to understand it again after you've stepped away + from it for a month. + + The conventional way of naming types and variables with + compound names is to use camel case, i.e. + myVariableName. This style is almost + universal in Haskell code. Regardless of your opinion of other + naming practices, if you follow a non-standard convention, your + Haskell code will be somewhat jarring to the eyes of other + readers. + + Until you've been working with Haskell for a substantial + amount of time, spend a few minutes searching for library + functions before you write small functions. This applies + particularly to ubiquitous types like lists, Maybe, + and Either. If the standard libraries don't + already provide exactly what you need, you might be able to + combine a few functions to obtain the result you desire. + + Long pipelines of composed functions are hard to read, where + long means a pipeline of more than three or four + elements. If you have such a pipeline, use a &let; or &where; + block to break it into smaller pipelines. Give each one of + these pipeline elements a meaningful name, then glue them back + together. If you can't think of a meaningful name for an + element, you probably can't describe what it's supposed to be + doing. + + Even though it's easy to resize a text editor window far + beyond 80 columns, this is still a very common window width. + Wider lines thus get wrapped in 80-column windows, which + severely hurts readability. Treating lines as no more than 80 + characters long limits the amount of code you can cram onto a + single line to a reasonably digestible amount. + + A Haskell implementation won't make a fuss about indentation + as long as your code follows the layout rules and can hence be + parsed unambiguously. That said, some layout patterns are + widely used. + + The ∈ keyword is usually aligned directly under the &let; + keyword, with the expression immediately following it. + + &Style.hs:goodLet; + + While it's legal to indent the ∈ + differently, or to let it dangle at the end of a + series of equations, the following would generally be considered + odd. + + &Style.hs:badLet; + + In contrast, it's usual to let a &do; dangle at the end of a + line, rather than sit at the beginning of a line. + + &Style.hs:do; + + Curly braces and semicolons, though legal, are almost never + used. There's nothing wrong with them; they just make code look + strange due to their rarity. They're really intended to let + programs generate Haskell code without having to implement the + layout rules, not for human use. + + &Style.hs:punctuation; + + If the right hand side of an equation starts on a new line, + it's usually indented a small number of spaces relative to the + name of the variable or function that it's defining. + + &Style.hs:indent; hunk ./en/ch09-find-dsl.xml 991 - - - If you find yourself proudly thinking that a particular - piece of code is fiendishly clever, consider whether you'll - be able to understand it again after you've stepped away - from it for a month. + The actual number of spaces used to indent varies, sometimes + within a single file. Depths of two, three, and four spaces are + about equally common. A single space is legal, but not very + visually distinctive, so it's easy to misread. hunk ./en/ch09-find-dsl.xml 996 - Until you've been working with Haskell for a substantial - amount of time, spend a few minutes searching for library - functions before you write small functions. This applies - particularly to ubiquitous types like lists, - Maybe, and Either. If the - standard libraries don't already provide exactly what you - need, you might be able to combine a few functions to obtain - the result you desire. + When indenting a &where; clause, it's best to make it + visually distinctive. hunk ./en/ch09-find-dsl.xml 999 - Long pipelines of composed functions are hard to read. - If you have one, use a &let; or &where; block to break it - down into smaller pipelines. Give each one of these - pipeline elements a meaningful name, then glue them back - together. If you can't think of a meaningful name for an - element, you probably can't describe what it's supposed to - be doing. - - + &Style.hs:where; addfile ./examples/ch09/Style.hs hunk ./examples/ch09/Style.hs 1 +{-- snippet goodLet --} +tidyLet = let foo = undefined + bar = foo * 2 + in undefined +{-- /snippet goodLet --} + +{-- snippet badLet --} +weirdLet = let foo = undefined + bar = foo * 2 + in undefined + +strangeLet = let foo = undefined + bar = foo * 2 in + undefined +{-- /snippet badLet --} + +{-- snippet punctuation --} +unusualPunctuation = + [ (x,y) | x <- [1..a], y <- [1..b] ] where { + b = 7; + a = 6 } + +preferredLayout = [ (x,y) | x <- [1..a], y <- [1..b] ] + where b = 7 + a = 6 +{-- /snippet punctuation --} + +commonDo, rareDo :: Monad m => m () + +{-- snippet do --} +commonDo = do + something <- undefined + return () + +-- not seen very often +rareDo = + do something <- undefined + return () +{-- /snippet do --} + +{-- snippet indent --} +normalIndent = + undefined + +strangeIndent = + undefined +{-- /snippet indent --} + +{-- snippet where --} +goodWhere = take 5 lambdas + where lambdas = [] + +alsoGood = + take 5 lambdas + where + lambdas = [] + +badWhere = -- legal, but ugly and hard to read + take 5 lambdas + where + lambdas = [] +{-- /snippet where --} }