Haskell “哈斯克尔”;相依;记录的字段?
我已定义了以下记录:Haskell “哈斯克尔”;相依;记录的字段?,haskell,record,Haskell,Record,我已定义了以下记录: data Option = Option { a :: Maybe String, b :: Either String Int } deriving (Show) 我是否需要强制规定,当a是无时,b必须是a左,当a是正时,b必须是a右?也许是幻影类型,或者别的什么?或者我必须将整个内容包装在一个或中,并使其成为或字符串(String,Int)?对于两种可能的形状,您应该只使用两个构造函数: data Option = NoA String |
data Option = Option {
a :: Maybe String,
b :: Either String Int
} deriving (Show)
我是否需要强制规定,当a是
无
时,b必须是a左
,当a是正
时,b必须是a右
?也许是幻影类型,或者别的什么?或者我必须将整个内容包装在一个或中,并使其成为或字符串(String,Int)
?对于两种可能的形状,您应该只使用两个构造函数:
data Option = NoA String | WithA String Int
当然,你应该根据他们所代表的事物给他们起更好的名字。幻影类型在这里绝对是过火了,我建议避免或者-左和右都不是非常自我记录的构造函数名称
如果将b字段的两个分支解释为表示相同的数据是有意义的,那么您应该定义一个反映这种解释的函数:
b :: Option -> MeaningOfB
b (NoA s) = ...
b (WithA t n) = ...
如果无论选择什么字段,字段都保持不变,则应使用所有字段创建一个新的数据类型,并将其包含在两个构造函数中。如果将每个构造函数设置为记录,则可以在每个构造函数中为公共字段指定相同的名称,这样就可以从任何选项
值中提取它,而无需对其进行模式匹配
基本上,想想字符串不存在意味着什么:其他字段有什么变化,什么保持不变?各施工人员应进行的任何变更;任何保持不变的东西都应该分解成它自己的类型。(总的来说,这是一个很好的设计原则!)
如果你有面向对象的背景,你可以用合成而不是继承的方式来思考这个问题,但是不要把类比做得太过分。我认为Haskell 2010在你以前的解决方案中没有任何东西允许这样做。我建议使用字符串(String,Int)
,或者使用同构类型,例如data Option=OptionA String | OptionB String Int
,其中构造函数有合理的名称。为了最好地回答这个问题,了解a
和b
的含义非常重要。为什么有时候你没有一个a
(例如,什么都没有
)?为什么可以将b
表示为String
或Int
?你为什么要实施你所说的限制?这给我的最初印象是b
没有很好的定义。