Haskell 另一个新类型与数据(风格问题)

Haskell 另一个新类型与数据(风格问题),haskell,coding-style,Haskell,Coding Style,我很清楚数据、新类型和类型之间的区别。我正在编写一个小脚本,它将构建某种语法树。几乎所有类型都有一个构造函数。我避免使用类型来加强安全性(在Haskell中,多个“不同”类型可能最终使用相同的类型)。在这种情况下,我不关心懒惰/严格,也不关心性能(这一部分绝不是性能关键)。我主要关注的是风格。我有三个选择: 仅使用数据。这感觉还可以,只是我有很多类型,只有一个构造函数和一个参数。代码看起来有点浪费。。。虽然我不在乎性能的提升,但我觉得这样做不对 仅使用newtype。在多参数的情况下,这导致了元

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

  • 仅使用
    数据
    。这感觉还可以,只是我有很多类型,只有一个构造函数和一个参数。代码看起来有点浪费。。。虽然我不在乎性能的提升,但我觉得这样做不对
  • 仅使用
    newtype
    。在多参数的情况下,这导致了元组的许多丑陋
  • 混合使用
    数据
    新类型
    ,这两种类型看起来有些不统一,有点烦人。。我希望以一种一致的方式声明所有类型

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

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

    其次,也是最重要的,
    newtype
    数据有不同的语义!
    newtype
    的构造函数是严格的,而
    data
    的构造函数则是非严格的,除非您明确使用严格字段。即使您不关心严格性,或者您的
    数据的所有字段都是严格的,仍然有一些字段是严格的

    我不认为一个构造函数、一个参数
    数据
    类型是浪费的——在语法上,它们和
    新类型
    一样轻,在语义上,对我来说似乎更重要

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


    通常,在包装现有类型时,出于编译时安全/抽象的目的,或者为了定义自己的实例,应该使用
    newtype
    ,并且每当类型恰好由单个字段组成时,应该使用
    data
    ,当我构建真正的程序时,我几乎总是使用
    newtype
    来表示具有单个构造函数和参数的数据类型,而
    数据
    则表示其他所有内容:

    data Foo = FooA | FooB Int
    data Bar = BarA Int Foo
    newtype Baz = Baz Bar
    
    至少,如果你发现自己在写作

    newtype Foo = Foo (X,Y)
    
    语义与

    因此,您最好使用
    数据
    版本,因为它更漂亮。确实如此

    data Foo = Foo Int
    newtype Bar = Bar Int
    
    在语义上确实有所不同,但对于“真正”的程序来说并不重要,因为我们不希望知道
    |
    Foo|
    之间的区别(因为所有值都是完全定义的)

    还有一件事需要注意:声明中的一致性是需要警惕的。它表明存在一个抽象级别,您没有在程序中进行编码,而是隐式地进行编码。查看是否可以对该级别进行编码,直到没有可利用的并行声明结构为止。这并不总是可能的,但要尽量靠近

    data Foo = Foo Int
    newtype Bar = Bar Int