在 Haskell 中设计数据类型时,我经常遇到的一个问题是要么使用求和类型,要么使用 Maybe Eithers 的记录。
一个简单的例子是对 FX 操作、即期或远期进行建模,其中唯一的区别是是否存在“到期”日期(一种方法是使用总和类型并明确指定它是即期还是前锋。
data Amount = Amount { amount :: Double, currency :: String }
data Fx = Spot { tranDate :: Day, soldAmount :: Amount, boughtAmount :: Amount }
| Forward { tranDate :: Day, paidAmount :: Amount, boughtAmount :: Amount , maturity :: Day}
另一种方法是将成熟度
作为“可能”
data Fx = Fx { tranDate :: Day
, soldAmount :: Amount
, boughtAmount :: Amount
, maturity (Maybe Day)
}
或者其他的
最佳答案
我不建议使用具有命名字段的求和类型。它们对于只存在于其中一个分支上的访问者来说是不安全的。如果您有重复的字段,它们就不是很干。
但是我不会将 Maybe
放在记录中,而是定义一个包装记录,如下所示:
data Spot = Spot
{ tranDate :: Day
, soldAmount :: Amount
, boughtAmount :: Amount
}
data Forward = Forward
{ spot :: Spot
, maturity :: Day
}
甚至可能还有 HasSpot
类型类,Spot
和 Forward
都可以实现。
但现在很难将 Spot 和 Forward 值放在同一个集合中。在这种情况下,也许可以使用像 (Maybe Day, Spot)
这样的类型。
但是,此答案的“包装”方法并不能很好地推广到多个可选字段。
关于haskell - 求和类型与 Maybes 的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26427582/