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