Sum类型与Maybes的记录

mb1*_*b14 2 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}
Run Code Online (Sandbox Code Playgroud)

另一种方法就是把它maturity作为"可能"

data Fx = Fx { tranDate :: Day
             , soldAmount :: Amount
             , boughtAmount :: Amount
             , maturity (Maybe Day)
             }
Run Code Online (Sandbox Code Playgroud)

或其他任何东西

dan*_*iaz 5

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

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

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

data Forward = Forward
    { spot :: Spot
    , maturity :: Day
    }
Run Code Online (Sandbox Code Playgroud)

也许甚至是HasSpot类型类为好,既SpotForward将实施.

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

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