我不太明白你有什么顾虑,但回答最后一行的问题:no,将求和类型与记录语法混合起来并不是一个好主意。一般来说,记录仍然是 Haskell 语言的一个弱点;他们根本不能很好地处理范围界定。只要您只有一些具有不同唱片公司的单独类型,通常就没有问题,但是一旦出现总和类型或名称冲突,情况就会变得相当糟糕。
特别是,Haskell 允许您使用记录字段访问器T1
任何类型值的构造函数T3
– print $ a (T2 'x')
将在没有警告的情况下编译,但在运行时给出相当难以预见的错误。
在您的示例中,幸运的是,您似乎可以轻松避免这种麻烦:
data T3 = T3_1 T1 | T3_2 T2
deriving (Show)
data T1 = T1 { a :: Int
, b :: Float}
deriving (Show)
data T2 = T2 { x :: Char }
deriving (Show)
现在,您可以编写的任何解构都将经过正确的类型检查以使其有意义。
And such a structure of meaningful, small specialised sub-types† is generally better to handle than a single monolithic type, especially if you have many functions that really deal only with part of the data structure.
另一方面是,解开构造函数的层会变得极其繁琐,但幸运的是,现在这个问题已经解决了:镜头库 http://lens.github.io/允许您非常整齐地组合访问器/修饰符。
说到已解决的问题:尼基塔·沃尔科夫 https://nikita-volkov.github.io/record/提出了一个非常好的概念来完全替换充满问题的记录语法。
†Um... actually these aren't subtypes in any proper sense of the word, but you get what I mean.