Shape
numberOfSides
可以是三角形,四边形等,具体取决于data MyRecord = MyRecord {
players :: [Player],
numOfPlayers :: Int
}
。
我的问题是:这两个领域是相关的。当一个字段更新时,是否有“触发”机制来更新另一个?如果这两个字段存在冲突,那么报告类型错误?
另一个相关场景:
numberOfPlayers
我想以某种方式根据players
的大小自动计算{{1}}。
PS:这是否与 GADT 和依赖类型有某种关联?
答案 0 :(得分:2)
在Haskell中,与OO语言不同,您无法修改字段。因此,通常的方法,即我认为你正在考虑的,有一个明确的“setter”在Haskell中没有意义。最简单的事情,这与DRY principle(在函数式语言以及OO语言中非常相关)完全一致,只是存储其中一个字段而另一个是访问者,如上所述在评论中。
-- deriving (...) clauses and other boilerplate omitted for brevity
data Shape = Triangle | Quad | Pentagon | Other
data MyRecord = MyRecord Int
numSides :: Shape -> Int
numSides Triangle = 3
numSides Quad = 4
numSides Pentagon = 5
numSides Other = 0
shape :: Int -> Shape
shape 3 = Triangle
shape 4 = Quad
shape 5 = Pentagon
shape _ = Other
makeMyRecord :: Shape -> MyRecord
makeMyRecord = MyRecord . numSides
numberOfSides :: MyRecord -> Int
numberOfSides (MyRecord x) = x
shapeOf :: MyRecord -> Shape
shapeOf = shape . numberOfSides
现在,Shape
可以是Enum
和Bounded
,如果您还没有这样做的话。从那里开始,shape
和numSides
可以根据自动生成的Enum
实例缩短。如果您希望能够从MyRecord
构建Int
,则可以导出数据构造函数或定义另一个makeMyRecord'
来执行此操作。现在,由于我们正在使用DRY原则,您可以让用户自由更新字段,另一个“字段”将会神奇地更新。
答案 1 :(得分:1)
我的问题是:这两个领域是相关的。是否有"触发器"更新一个字段时更新另一个的机制?如果这两个字段存在冲突,那么报告类型错误?
PS:这是否与GADT和依赖类型有关?
这与依赖类型有关,但与GADT无关。由于这是Haskell,我建议只需在记录中存储边数,然后编写函数numTypes :: Int -> Shape
。