7

作为一名 Haskell(GHC 平台)初学者,我遇到了处理与涉及货币/货币操作的业务领域相关的数据类型和算术运算的问题,我正在寻找解决方案。

我正在开发应该与(独立)会计模块(通过 Web 服务)交互的应用程序,同时具有用于存储在单独数据库(PostgreSQL)中的临时数据输入的(Web)用户界面。

我来自 C#/F# 环境,System.Decimal 涵盖了那里的所有核心需求。如果我错了,请纠正我,但 Haskell 似乎没有可以被视为等效的集成(默认)数据类型。

理想的选择是提供任意精度算术或至少符合 Decimal128 (IEEE 754) 的数据类型。该类型应支持舍入(最接近,远离零,如果可能还与偶数相关)和以下操作:加法、减法、乘法、除法(理想情况下也是平方/根)。还应支持类型之间的转换。

据我所知,Hackage 上有两个 Haskell 模块应该可以准确地执行计算 - Data.Fixed 和 Data.Decimal (顺便说一句,有什么方法可以在 Haskell 中创建自定义文字 - 例如复制 123.45m来自 F#?)。至少后者会据我所知(在快速测试之后)启用我在上一段中描述的大部分内容,但是当我添加一个数据库(通过 Persistent/HDBC 的 PostgreSQL)和一个 Web 框架(YESOD)时混合的东西看起来不那么桃色。那里似乎缺乏支持。

是否有任何其他组合能够以最小的摩擦实现我所描述的端到端(数据输入 => 数据处理 => 存储)(例如,在从数据库加载后从字符串手动转换似乎很奇怪,拥有一种非常强类型的语言)并且不损失精度(欢迎任何指针)?

4

1 回答 1

3

我正在制作一个 Yesod 应用程序,并使用 Database.Persist。出于我的目的,我将创建一个包装 Data.Fixed 值的新类型,并使用 Int64 字段,如下所示:

newtype Dollars = Dollars { unDollars :: Centi } deriving (Eq, Num)

instance PersistField Dollars where
   toPersistValue = PersistInt64 . fromIntegral . fromEnum . unDollars
   fromPersistValue (PersistInt64 c) = Right . Dollars . toEnum . fromIntegral $ c
   fromPersistValue x = Left . Text.pack $ "Expected Int64 counting cents, got: " ++ show x
于 2014-05-30T22:05:50.257 回答