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

时间:2015-10-22 03:55:33

标签: 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)。在三个表示中,哪一个是更可取的,使用具有记录语法的构造函数和不具有记录语法的构造函数的立场是什么?

1 个答案:

答案 0 :(得分:9)

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