Haskell“依赖”字段的记录?

时间:2011-12-24 17:11:24

标签: haskell record

我已经定义了以下记录:

data Option = Option {
    a    :: Maybe String,
    b    :: Either String Int
} deriving (Show)

我是否有强制执行,当a为Nothing时,b必须为Left,当a为Just时,b必须为Right?也许用幻影类型或其他东西?或者我必须将整个事物包裹在Either中并使其成为Either String (String, Int)吗?

1 个答案:

答案 0 :(得分:18)

你应该只为两种可能的形状使用两个构造函数:

data Option = NoA String | WithA String Int

当然,你应该根据他们的代表给他们更好的名字。幻影类型肯定是矫枉过正的,我建议避免Either - LeftRight不是非常自我记录的构造函数名称。

如果将b字段的两个分支都解释为表示相同的数据是有意义的,那么您应该定义一个反映这种解释的函数:

b :: Option -> MeaningOfB
b (NoA s) = ...
b (WithA t n) = ...

如果您的字段保持不变,无论选择何种,您都应该为所有字段创建一个新的数据类型,并将其包含在两个构造函数中。如果您将每个构造函数都设为记录,则可以在每个构造函数中为公共字段指定相同的名称,以便您可以从任何Option值中提取它,而无需对其进行模式匹配。

基本上,考虑字符串不存在的意味着什么:它对其他字段有什么改变,什么保持不变?各个构造函数应该发生什么变化;无论什么样的停留都应该考虑到它自己的类型。 (这一般是一个很好的设计原则!)

如果你来自OOP背景,你可以在构思而不是继承的推理方面考虑这一点 - 但是尽量不要把这个类比推得太远。