简体   繁体   English

使用带有多个构造函数的代数数据类型的记录语法

[英]Using record syntax with algebraic data types with multiple constructors

The following data type is a representation of a phosphatidic acid (PA - a subclass of lipid). 以下数据类型是磷脂酸(PA-脂质的亚类)的代表。 Using mass spectrometry, there are different levels of structural detail that may be acquired (ie, from simply knowing the mass of the lipid all the way to having a full structural characterisation). 使用质谱法,可以获得不同水平的结构细节(即,从简单地知道脂质的质量一直到具有完整的结构表征)。

I currently have the PA data type as- 我目前有PA数据类型 -

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

This combines constructors with record syntax with those that don't (possibly a bad idea). 这将构造函数与记录语法结合在一起(不太可能是一个坏主意)。 Alternatively, I could do one of the following - 或者,我可以做以下其中一项 -

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

I am not currently using the accessor functions paSn1 and paSn2 but my current thinking is that they could be useful later on. 我目前没有使用访问器函数paSn1和paSn2,但我目前的想法是它们以后可能会有用。 The later alternative is much cleaner though and and also avoids having to deal with multiply field names for different records (until the OverloadedRecordFields extension is added to GHC). 后面的替代方案虽然更清晰,但也避免了必须处理不同记录的多个字段名称(直到OverloadedRecordFields扩展名添加到GHC)。 Of the three representations, which one is preferable and what is the stance on using constructors with record syntax with those that don't? 在三个表示中,哪一个是更可取的,使用具有记录语法的构造函数和不具有记录语法的构造函数的立场是什么?

Using accessor functions for datatypes with more than one constructor is widely discouraged, because these functions will be partial. 对于具有多个构造函数的数据类型使用访问器函数是非常不鼓励的,因为这些函数将是部分函数。 I would think you could probably do better using prisms and/or traversals from the lens package. 我认为使用lens包中的棱镜和/或遍历可能会做得更好。 Prisms provide a lensy alternative to pattern matching and constructor application. 棱镜提供了模式匹配和构造器应用的透镜替代方案。 Traversals (more to the point) let you deal with zero or more things, including fields that may or may not be there. 遍历(更重要的是)允许您处理零个或多个事物,包括可能存在或不存在的字段。 The magic Template Haskell functions for making the traversals will, I believe) require you to include accessors (with names that start with _ ), but you never need to use those directly or export them. 我认为,用于进行遍历的神奇的模板Haskell函数将要求您包含访问器(名称以_开头),但您永远不需要直接使用它们或导出它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM