【问题标题】:Yet another newtype vs. data (stylistic issue)另一个新类型与数据(风格问题)
【发布时间】:2012-03-06 19:46:46
【问题描述】:

我非常了解datanewtypetype 之间的区别。我正在编写一个小脚本,它将构建某种语法树。 几乎所有类型都有一个构造函数。我避免type 强制安全(多个“不同”类型可能最终在 Haskell 中具有相同的类型)。在这种情况下,我不关心惰性/严格性,也不关心性能(这部分绝不是性能关键)。我主要关注风格。我有三个选择:

  1. 仅使用data。这感觉不错,除了我有许多类型,只有一个构造函数和一个参数。代码看起来有些浪费……虽然我不在乎性能提升,但就是感觉不对。
  2. 仅使用newtype。在多个参数的情况下,这会导致元组出现很多丑陋。
  3. 混合使用 datanewtype,它们看起来有点不统一且有点烦人。我宁愿以单一一致的方式声明所有类型。

我在选择 1 和 3 之间进退两难。

【问题讨论】:

    标签: haskell coding-style


    【解决方案1】:

    在这种情况下,出于几个原因,我会普遍使用data。首先,为了与多参数情况保持一致(应该肯定data,而不是newtype)。

    其次,最重要的是,newtypedata 具有不同的语义newtype 的构造函数是严格的,而 data 的构造函数是非严格的,除非您明确使用严格字段。即使你不关心严格,或者你datas的所有字段都是严格的,仍然有一些subtle differences

    我不认为只有一个构造函数、一个参数的 data 类型是浪费的——从语法上讲,它们和 newtype 一样轻巧,从语义上讲,对我来说似乎更重要。

    您说您不关心性能,但如果 data 的运行时装箱开销确实不方便,那么您可以混合使用它们,只要您知道语义差异。但是,如果您使用 -funbox-strict-fields,那么 GHC 可能能够为您优化掉单构造函数、单参数 datas,前提是它们在其他数据类型中作为严格字段出现。

    一般来说,您应该在包装现有类型时使用newtype,以实现编译时安全/抽象,或定义您自己的实例,并在该类型恰好是时使用data由单个字段组成,而不是包装器。

    【讨论】:

      【解决方案2】:

      当我构建真正的程序时,我几乎总是使用newtype 来处理具有单个构造函数和参数 的数据类型,而data 来处理其他所有事情:

      data Foo = FooA | FooB Int
      data Bar = BarA Int Foo
      newtype Baz = Baz Bar
      

      至少,如果你发现自己在写作

      newtype Foo = Foo (X,Y)
      

      语义相同

      data Foo = Foo X Y
      

      所以您不妨使用data 版本,因为它更漂亮。确实

      data Foo = Foo Int
      newtype Bar = Bar Int
      

      确实在语义上有所不同,但对于“真正的”程序来说并不重要,因为我们不需要知道 _|_Foo _|_ 之间的区别(因为所有值都是完全- 无论如何定义)。

      还有一点需要注意:声明的一致性是需要警惕的。它表明您没有在程序中编码的抽象级别,您正在隐含。看看您是否可以对该级别进行编码,直到没有可利用的并行声明结构。这并不总是可能的,但请尝试接近。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-14
        • 2017-07-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多