作为一名Haskell(GHC平台)初学者,我遇到了一个处理与业务领域相关的数据类型和算术运算的问题,该问题涉及货币/货币操作,我正在寻找解决方案。
我正在开发一个应用程序,该应用程序应该与(独立的)会计模块接口(通过web服务),同时具有一个(web)用户界面,用于存储在单独数据库(PostgreSQL)中的特殊数据输入。
我来自C#/F#环境和系统。Decimal涵盖了那里的所有核心需求。如果我错了,请纠正我,但Haskell似乎没有一个可以被视为等效的集成(默认)数据类型。
理想的选择是提供任意精度算术的数据类型,或者至少是十进制128(IEEE 754)的数据类型。该类型应该支持四舍五入(最接近,远离零,如果可能的话,还可以连接到偶数)和以下操作:加、减、乘、除(理想情况下还可以是平方/根)。还应支持类型之间的转换。
据我所知,Hackage上有两个Haskell模块应该准确地执行计算-Data.Fixed和Data.Decimal(顺便说一句,有没有任何方法可以在Haskell中创建自定义文本,例如从F#复制123.45m?)。至少据我所知,后者(经过快速测试)能够实现我在上一段中描述的大部分功能,但当我将DB(PostgreSQL via Persistent/HDBC)和web框架(YESOD)添加到混合中时,事情看起来就不那么好了。那里似乎缺乏支持。
有没有其他组合可以实现我所描述的端到端(数据输入=>数据处理=>存储),摩擦最小(例如,从DB加载后从字符串手动铸造似乎很奇怪,有一种非常强类型的语言),并且不会损失精度(欢迎使用任何指针)?
我正在制作一个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