Haskell Data.Decimal作为Aeson类型

4

你能否使用Aeson包解析JSON中的Data.Decimal?

假设我有以下JSON:

{
    "foo": 5.231,
    "bar": "smth"
}

还有以下记录类型:

data test { foo :: Data.Decimal
          , bar :: String } deriving Generic

使用

instance FromJSON test
instance ToJSON test

如果没有 "foo" 的 Data.Decimal 值,这将起作用。
据我了解,我需要手动创建一个 Data.Decimal 的 FromJSONToJSON 实例(用于转换回 JSON),因为它不是从 Generic 派生的。我该怎么做?
提前感谢。

5
为了避免编写孤立实例,您可以将Decimal包装在newtype中,然后按照aeson文档中的“手写实例”部分进行操作。然而,更明智的做法很可能是从Data.Decimal切换到Data.Scientific(来自于scientific包),因为它具有由aeson提供的实例。 - duplode
你找到答案了吗? - Saurabh Nanda
1
我转向了Data.Scientific。 - PiMaker
1个回答

0

我知道这是一个老帖子,但可能有助于某些人。以下是我如何将十进制转换为/从 json(我从一堆其他代码中组装了这段代码,现在没有其源代码):

instance A.ToJSON (DecimalRaw Integer) where
  -- maybe this is not the best, but it works
  toJSON d = A.toJSON $ show d

instance A.FromJSON (DecimalRaw Integer) where
  parseJSON = A.withText "Decimal" (go . (read :: String -> [(DecimalRaw Integer, String)]) . T.unpack)
    where
      go [(v, [])] = return v
      go (_ : xs) = go xs
      go _ = fail "Could not parse number"

这段代码是错误的。首先,你应该使用reads函数而不是read;其次,case go (_:xs) 应该导致失败,而不是递归调用。 - Denis Krivitski
谢谢,最终我使用了 parseJSON = A.withScientific "Decimal" (return . right . eitherFromRational . toRational) 它运行良好。 - RecencyEffect

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接