使用 Aeson 解析 Haskell 中的嵌套 JSON
Parsing a nested JSON in Haskell with Aeson
我正在尝试学习 Haskell 中的 Aeson 图书馆。 现在我正在尝试解析一个简单的 JSON 文件,它看起来像这样
{
"Meta Data": {
"1: Symbol": "MSFT",
"2: Indicator": "Relative Strength Index (RSI)",
"3: Last Refreshed": "2018-10-15",
"4: Interval": "weekly",
"5: Time Period": 10,
"6: Series Type": "open",
"7: Time Zone": "US/Eastern Time"
},
"Technical Analysis: RSI": {
"2018-10-15": {
"RSI": "54.5653"
},
"2018-10-12": {
"RSI": "63.0279"
},
"2018-10-05": {
"RSI": "74.7519"
},
"2018-09-28": {
"RSI": "72.1573"
},
"2018-09-21": {
"RSI": "74.8123"
},
"2018-09-14": {
"RSI": "66.7116"
},
"2018-09-07": {
"RSI": "75.8051"
},
..and so on
借助 Aeson 上的本教程 Aeson: the tutorial 特别是 "Nested records" 部分
这就是我目前所知道的。
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Tesst where
import Data.Aeson
import qualified Data.ByteString.Lazy as B
import Data.Time
import GHC.Exts
import GHC.Generics
import Network.HTTP.Conduit (simpleHttp)
data TechinicalAnalysis = TechinicalAnalysis {
name :: String,
date :: String,
rsi :: String
} deriving (Show, Generic)
instance FromJSON TechinicalAnalysis where
parseJSON = withObject "RSI Quote" $
\o -> do
rsiQuote <- o .: "Technical Analysis: RSI"
date <- rsiQuote .: "2018-10-16"
rsi <- date .: "RSI"
return TechinicalAnalysis {..}
main :: IO ()
main = do
putStrLn "Which ticker? "
symbolToQuote <- getLine
d <- (eitherDecode <$> simpleHttp ("https://www.alphavantage.co/query?function=RSI&interval=weekly&time_period=10&series_type=open&apikey==FI2KMCSDSAE&symbol=" ++ symbolToQuote)) :: IO (Either String TechinicalAnalysis)
case d of
Left e -> print e
Right qt -> print (rsi qt)
我的目标是从 link 的 JSON 文件中获取最新的 "RSI" 引用。
我不确定现在该怎么做,所以出于测试目的,我在 parseJSON
部分手动设置了键 "2018-10-16"
。
我收到的错误消息 运行 代码是
• Couldn't match type ‘unordered-containers-0.2.9.0:Data.HashMap.Base.HashMap
Data.Text.Internal.Text Value’
with ‘[Char]’
Expected type: String
Actual type: Object
• In the ‘date’ field of a record
In the first argument of ‘return’, namely ‘TechinicalAnalysis {..}’
In a stmt of a 'do' block: return TechinicalAnalysis {..}
|
27 | return TechinicalAnalysis {..}
| ^^^^^^^^^^^^^^^^^^^^^^^
我认为这告诉我 date
从 date <- rsiQuote .: "2018-10-15"
得到的响应不是我所期望的。
我解决了问题。
什么 .:
returns 的类型是 Object
而不是 String
所以不用这个
data TechinicalAnalysis = TechinicalAnalysis {
name :: String,
date :: String,
rsi :: String
} deriving (Show, Generic)
我很生气
newtype TechinicalAnalysis = TechinicalAnalysis {
rsi :: String
} deriving (Show, Generic)
并且运行顺畅。