代码之家  ›  专栏  ›  技术社区  ›  Alexey Romanov

良好的haskell编码标准

  •  74
  • Alexey Romanov  · 技术社区  · 16 年前

    有人能为haskell提供一个好的编码标准链接吗?我找到了 this this 但它们还远远不够全面。更不用说haskellwiki一个包含“小心使用类”和“定义符号中缀标识符应该只留给库作者”这样的“gem”。

    5 回复  |  直到 12 年前
        1
  •  90
  •   Ralph java.is.for.desktop    13 年前

    这个问题很难回答。我希望你的回答能得到一些好的结果。同时,这里是我在初学者代码中发现的错误或其他恼人的事情的目录。Kornel Kisilewicz指向的Cal-Tech风格页面有一些重叠。我的一些建议和haskellwiki的“gems”一样含糊不清,毫无用处,但我希望至少它是更好的建议。

    • 设置代码的格式,使其适合80列。(高级用户可能更喜欢87或88;除此之外,这是在推动它。)

    • 别忘了 let 绑定和 where 子句创建一个相互递归的定义嵌套, 序列 定义。

    • 利用 在哪里? 子句,尤其是它们查看已经在作用域中的函数参数的能力(很好的模糊建议)。如果你真的在搜索haskell,你的代码应该有更多 在哪里? -绑定比 -绑定。太多 -绑定是未构造的ML程序员或Lisp程序员的标志。

    • 避免使用多余的括号。有些地方多余的括号特别令人讨厌

      • 周围的条件 if Expression(给你打上品牌,让你成为一个不受约束的C程序员)

      • 在函数应用程序周围,它本身就是中缀运算符的参数( 函数应用程序比任何中缀运算符绑定得更紧密 . 这一事实应该被烧掉到每个哈斯凯勒的大脑中,就像我们的恐龙已经烧掉了APL的从右到左扫描规则一样。)

    • 在中缀运算符周围放置空格。在元组文本中的每个逗号后加一个空格。

    • 在函数与其参数之间使用空格,即使参数用括号括起来。

    • 使用 $ 操作员明智地削减括号。意识到 $ 和中缀 . :

      f $ g $ h x == (f . g . h) x == f . g . h $ x
      
    • 不要忽视内置的 Maybe Either 类型。

    • 从不写 if <expression> then True else False ;正确的短语很简单 <expression> .

    • 不要使用 head tail 当你可以使用模式匹配。

    • 不要忽略带中缀点运算符的函数组合。

    • 小心使用换行符。换行符可以提高可读性,但需要权衡:您的编辑器一次只能显示40行。如果你需要同时阅读和理解一个大函数,你不能过度使用换行符。

    • 几乎总是喜欢 -- {- ... -} 评论。有支撑的注释可能适用于大型标题。

    • 给每个顶级函数一个显式类型签名。

    • 如果可能,对齐 —— 线, = 符号,甚至出现在相邻行中的括号和逗号。

    • 由于受到GHC Central的影响,我对使用的偏好非常温和 camelCase 对于导出的标识符和 short_name 带下划线的本地 在哪里? 绑定或 -绑定变量。

        2
  •  27
  •   Mikhail Glushenkov    14 年前

    一些好的拇指规则:

    • 咨询 HLint 以确保您没有多余的大括号,并且您的代码没有毫无意义地指向完整的地方。
    • 避免重新创建现有的库函数。 Hoogle 可以帮你找到它们。
      • 通常情况下,现有的库函数比将要生成的函数更通用。例如,如果你想 Maybe (Maybe a) -> Maybe a 然后 join 做其他事情。
    • 参数命名和文档有时很重要。
      • 像这样的功能 replicate :: Int -> a -> [a] 很明显,每个参数都在做什么,仅从它们的类型来看。
      • 对于采用同一类型的多个参数的函数,例如 isPrefixOf :: (Eq a) => [a] -> [a] -> Bool ,参数的命名/文档更重要。
    • 如果一个函数的存在只是为了服务于另一个函数,而在其他方面并不有用,并且/或者很难为它取一个好的名称,那么它可能应该存在于它的调用方的名称中。 where 子句而不是在模块的作用域中。
    • 干的
      • 适当时使用模板haskell。
      • 功能组合,如 zip3 , zipWith3 , zip4 , zipWith4 等等都很不错。使用 Applicative 风格与 ZipList 而是S。你可能根本不需要这样的功能。
      • 自动派生实例。这个 derive 包可以帮助您派生类型类的实例,例如 Functor (只有一种正确的方法可以使类型成为 函子 )
    • 更通用的代码有几个好处:
      • 它更有用,更可重用。
      • 它不太容易出错,因为有更多的约束。
        • 例如,如果你想编程 concat :: [[a]] -> [a] 注意它是如何变得更一般的 join :: Monad m => m (m a) -> m a .编程时出错的空间较小 参加 因为编程时 concat 你可以错误地把清单倒过来 参加 你能做的事情很少。
    • 在代码的许多地方使用同一堆Monad Transformers时,请将其作为类型的同义词。这将使类型更短、更简洁、更易于批量修改。
    • 小心“懒惰的IO”。例如 readFile 在读取文件时,不会真正读取文件的内容。
    • 避免缩进太多以至于找不到代码。
    • 如果您的类型在逻辑上是一个类型类的实例,请将其设置为实例。
      • 该实例可以替换您可能考虑使用熟悉的接口函数的其他接口函数。
      • 注意:如果有多个逻辑实例,请为这些实例创建newtype包装器。
      • 使不同的实例保持一致。如果这个清单 应用的 举止像 齐普拉斯主义者 .
        3
  •  6
  •   Kornel Kisielewicz    16 年前

    我建议你看看这个 style checker .

        4
  •  6
  •   jberryman    16 年前
    • 我喜欢尝试组织功能 无点式构图 尽可能多地做事情 像:

      func = boo . boppity . bippity . snd
          where boo = ...
                boppity = ...
                bippity = ...
      
    • 我只喜欢使用($)来避免嵌套parens或长括号表达式

    • ……我还以为我还有一些,哦,好吧。

        5
  •  4
  •   d12frosted    12 年前

    我发现很好的标记文件几乎涵盖了haskell代码样式的各个方面。它可以用作备忘单。你可以在这里找到它: link