我正在使用埃森来解析json引用的雅虎API的数据。一句名言可能是这样的:
{
"date": "2010-03-10",
"Date": "2010-03-10",
"Open": "0.37",
"High": "0.37",
"Low": "0.34",
"Close": "0.35",
"Volume": "443000",
"Adj_Close": "0.35"
}(这是使用这 YQL查询)
正如你所看到的,这些数字被引用。我可以编写这样的fromJSON实现:
instance FromJSON Quote where
parseJSON (Object o) =
Quote <$> o .: "Date"
<*> o .: "Open"
<*> o .: "High"
<*> o .: "Low"
<*> o .: "Close"
<*> o .: "Volume"
parseJSON _ = mzero这和推导出来的一样。不幸的是,只有当我希望Open、High、Low等成为文本类型时才有效。如果我尝试将其中的任何字段作为Double (例如),解析就会失败。
我可以写这个:
<*> (fmap read $ o .: "Open")得到任何我喜欢的东西,但是这使用read,这是一个部分函数。如何在不使用部分函数的情况下获得上述功能?
发布于 2013-10-30 03:47:20
首先,找到一个安全的读取函数。我不得不去把它踢开。
其次,你必须使用更多的应用程序才能获得选择。在下面的代码中,我使用readMay进行安全读取,并在应用read实例时创建了一个帮助函数来提取字段。
{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}
import Safe
import Data.Aeson
import Data.Aeson.Types (Parser)
import Data.Text as T
import Data.Word
import Control.Applicative
import Control.Monad
data Quote = Quote Text Double Double Double Double Word64
instance FromJSON Quote where
parseJSON (Object o) = do
let readField :: (Read a) => T.Text -> Parser a
readField f = do
v <- o .: f
case readMay (T.unpack v) of
Nothing -> fail $ "Bad Field: " ++ T.unpack f
Just r -> return r
Quote <$> o .: "Date"
<*> readField "Open"
<*> readField "Close"
<*> readField "Low"
<*> readField "High"
<*> readField "Volume"
parseJSON _ = mzerohttps://stackoverflow.com/questions/19672415
复制相似问题