用于幻影类型货币的用例

幻像类型对于处理数据非常有用,它们具有相同的表示形式,但在逻辑上并不是同一类型。

一个很好的例子是处理货币。如果你使用货币,你绝对不希望例如添加两种不同的货币。5.32€ + 2.94$ 的结果货币是什么?它没有定义,没有充分的理由这样做。

对此的解决方案可能如下所示:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

data USD
data EUR

newtype Amount a = Amount Double
                 deriving (Show, Eq, Ord, Num)

GeneralisedNewtypeDeriving 扩展允许我们为 Amount 类型派生 Num。GHC 重用了 DoubleNum 实例。

现在,如果你使用例如 (5.0 :: Amount EUR) 代表欧元金额,你已经解决了在类型级别保持双金额分开而不会引入开销的问题。像 (1.13 :: Amount EUR) + (5.30 :: Amount USD) 这样的东西会导致类型错误,并要求你适当地处理货币转换。

可以在 haskell wiki 文章中找到更全面的文档