Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell “哈斯克尔”;相依;记录的字段?_Haskell_Record - Fatal编程技术网

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
没有很好的定义。