haskell - 将记录语法与具有多个构造函数的代数数据类型结合使用

标签 haskell algebraic-data-types

以下数据类型代表磷脂酸(PA - 脂质的一个子类)。使用质谱法,可以获取不同级别的结构细节(即,从简单地了解脂质的质量一直到具有完整的结构表征)。

我目前的 PA 数据类型为 -

data PA   = ClassLevelPA       IntegerMass
          | CombinedRadylsPA   CombinedRadyls
          | UnknownSnPA        Radyl Radyl
          | KnownSnPA          { paSn1 :: Radyl
                               , paSn2 :: Radyl }
          deriving (Show, Eq, Ord)

这将具有记录语法的构造函数与不具有记录语法的构造函数结合起来(可能是一个坏主意)。或者,我可以执行以下操作之一 -

data PA   = ClassLevelPA       { paIntegerMass :: IntegerMass }
          | CombinedRadylsPA   { paCombinedRadyls :: CombinedRadyls }
          | UnknownSnPA        { paR1 :: Radyl 
                               , paR2 :: Radyl }
          | KnownSnPA          { paSn1 :: Radyl
                               , paSn2 :: Radyl }

data PA   = ClassLevelPA       IntegerMass
          | CombinedRadylsPA   CombinedRadyls
          | UnknownSnPA        Radyl Radyl
          | KnownSnPA          Radyl Radyl

我目前没有使用访问器函数 paSn1 和 paSn2,但我目前的想法是它们以后可能会有用。后者的替代方案更加简洁,并且还避免了处理不同记录的多个字段名称(直到 OverloadedRecordFields 扩展添加到 GHC 中)。在这三种表示形式中,哪一种更可取?对于使用具有记录语法的构造函数和不使用记录语法的构造函数的立场是什么?

最佳答案

广泛不鼓励对具有多个构造函数的数据类型使用访问器函数,因为这些函数将是部分的。我认为您可能可以使用 lens 包中的 prisms 和/或 traversals 做得更好。棱镜为模式匹配和构造函数应用提供了一种透镜替代方案。遍历(更重要的是)让您可以处理零个或多个事物,包括可能存在或不存在的字段。我相信,用于进行遍历的神奇 Template Haskell 函数将要求您包含访问器(名称以 _ 开头),但您永远不需要直接使用它们或导出它们。

关于haskell - 将记录语法与具有多个构造函数的代数数据类型结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33273164/

相关文章:

haskell - 为什么这些 Haskell Parsec 组合器的顺序很重要?

Haskell:通过 "Principled Transformations"简化函数

rust - 减少深度嵌套属性的匹配缩进

algebraic-data-types - idris 案例/归纳策略

haskell - 如何将函数映射到嵌套数据结构的一部分?

haskell - Haskell中的"Dependent optional"数据

支持标记联合的序列化格式

具有代数数据类型的 Haskell 类型类

Ocaml 通过推断类型与值的接近程度消除歧义?

haskell - 如何在同一个函数中订阅多个 Redis channel ?