Sum类型与Maybes的记录

时间:2014-10-17 14:46:43

标签: haskell

我在Haskell中设计数据类型时经常遇到的一个问题是使用sum类型或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}

另一种方法是将maturity作为“可能”

data Fx = Fx { tranDate :: Day
             , soldAmount :: Amount
             , boughtAmount :: Amount
             , maturity (Maybe Day)
             }

或其他任何东西

2 个答案:

答案 0 :(得分:5)

我不建议使用具有命名字段的和类型。它们对仅存在于其中一个分支上的访问器不安全。如果你有重复的字段,它们就不会很干。

但是我不是将Maybe放在记录中,而是定义一个包装记录,如下所示:

data Spot = Spot 
    { tranDate :: Day
    , soldAmount :: Amount
    , boughtAmount :: Amount 
    }

data Forward = Forward
    { spot :: Spot
    , maturity :: Day
    }

甚至可能是HasSpot类型类,SpotForward都会实现。

但现在很难将Spot和Forward值放在同一个集合中。在这种情况下,也许可以使用类似(Maybe Day, Spot)的类型。

"包装"但是,这个答案的方法并不能很好地概括为多个可选字段。

答案 1 :(得分:1)

第二个例子没有很好的沟通。你必须检查maturity以区分前锋和现场。总和类型传达得更好。