Haskell 将记录语法与代数数据类型以及多个构造函数一起使用

Haskell 将记录语法与代数数据类型以及多个构造函数一起使用,haskell,algebraic-data-types,Haskell,Algebraic Data Types,以下数据类型是磷脂酸(PA-脂质的一个亚类)的表示。使用质谱分析法,可以获得不同层次的结构细节(即,从简单地知道脂质的质量到具有完整的结构特征) 我目前的PA数据类型为- data PA = ClassLevelPA IntegerMass | CombinedRadylsPA CombinedRadyls | UnknownSnPA Radyl Radyl | KnownSnPA {

以下数据类型是磷脂酸(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
包中的棱镜和/或遍历做得更好。棱镜为模式匹配和构造器应用提供了一种透镜替代方案。遍历(更切中要害)允许您处理零个或多个内容,包括可能存在或不存在的字段。我相信,用于进行遍历的神奇模板Haskell函数将要求您包含访问器(名称以
\uuuu
开头),但是你永远不需要直接使用或导出它们。

如果你现在不需要,我会选择最后一个-你可能会一直在进行模式匹配,在我看来,混合的模式是危险的,因为生成的访问函数是部分的(例如
paR1(ClassLevelPA-im)
)谢谢你的回答。编写部分函数是我当然想避免的事情,所以我会去掉它们。一定要看看
lens
软件包。使用不总是匹配的构造函数(即数据类型只有一个构造函数的情况)确实非常容易。部分字段由遍历而不是棱柱来处理。@AndrásKovács,这样更好吗?@MichaelT两年,没有接受的答案?顺便说一下,我想您可以使用一个普通的旧记录,其中的字段用
包装,可能是