如何在不声明单个类型的情况下使用 Aeson 解析 JSON
How to parse JSON with Aeson without declaring individual types
(Haskell新手提醒)
这是我正在努力处理的代码片段。基本上,我从 websocket 获取一个 JSON,我想使用 Aeson 解析它,而不需要为每个响应定义单独的数据类型。
import Data.Aeson
import qualified Network.WebSockets as WS
aria2WebsocketReceiver :: WS.Connection -> IO ()
aria2WebsocketReceiver conn = do
msg <- WS.receiveData conn
let res = decode msg
let v = flip parseMaybe res $ \o -> do
r <- o .: "result"
version <- r .: "version"
enabledFeatures <- r .: "enabledFeatures"
id_ <- r .: "id"
return $ "version=" ++ version
putStrLn (show v)
aria2WebsocketReceiver conn
以下是我 运行 遇到的编译错误:
Nightwatch/Telegram.hs:244:13:
No instance for (FromJSON a0) arising from a use of ‘decode’
The type variable ‘a0’ is ambiguous
Relevant bindings include
res :: Maybe a0 (bound at Nightwatch/Telegram.hs:244:7)
Note: there are several potential instances:
instance FromJSON Chat -- Defined at Nightwatch/Telegram.hs:90:10
instance FromJSON Message
-- Defined at Nightwatch/Telegram.hs:106:10
instance FromJSON TelegramResponse
-- Defined at Nightwatch/Telegram.hs:122:10
...plus two others
In the expression: decode msg
In an equation for ‘res’: res = decode msg
In the expression:
do { msg <- WS.receiveData conn;
let res = decode msg;
let v = flip parseMaybe res $ ...;
putStrLn (show v);
.... }
Nightwatch/Telegram.hs:246:44:
Couldn't match type ‘Maybe a0’
with ‘unordered-containers-0.2.5.1:Data.HashMap.Base.HashMap
Text Value’
Expected type: Object
Actual type: Maybe a0
Relevant bindings include
o :: Maybe a0 (bound at Nightwatch/Telegram.hs:245:34)
res :: Maybe a0 (bound at Nightwatch/Telegram.hs:244:7)
In the first argument of ‘(.:)’, namely ‘o’
In a stmt of a 'do' block: r <- o .: "result"
我基本上是在尝试复制 https://hackage.haskell.org/package/aeson-0.10.0.0/docs/Data-Aeson.html
中给出的 "Working with the AST" 示例
感谢 Cale 在 #haskell 这里是工作代码:
aria2WebsocketReceiver :: WS.Connection -> IO ()
aria2WebsocketReceiver conn = do
msg <- WS.receiveData conn
let v = do res <- decode msg
flip parseMaybe res $ \o -> do
r <- o .: "result"
version <- r .: "version"
return $ "version=" ++ (version :: String)
putStrLn (show v)
aria2WebsocketReceiver conn
之前的代码存在三个问题:
decode msg
的类型是 Maybe
,需要在单独的 do
块中。
- 由于
{-# LANGUAGE OverloadedStrings #-}
编译器无法推断 version
的类型,因此出现 (version :: String)
提示。
- 同样,
enabledFeatures
和 id_
被赋值但没有在任何地方使用,这在类型推断中引起了更多问题。
(Haskell新手提醒)
这是我正在努力处理的代码片段。基本上,我从 websocket 获取一个 JSON,我想使用 Aeson 解析它,而不需要为每个响应定义单独的数据类型。
import Data.Aeson
import qualified Network.WebSockets as WS
aria2WebsocketReceiver :: WS.Connection -> IO ()
aria2WebsocketReceiver conn = do
msg <- WS.receiveData conn
let res = decode msg
let v = flip parseMaybe res $ \o -> do
r <- o .: "result"
version <- r .: "version"
enabledFeatures <- r .: "enabledFeatures"
id_ <- r .: "id"
return $ "version=" ++ version
putStrLn (show v)
aria2WebsocketReceiver conn
以下是我 运行 遇到的编译错误:
Nightwatch/Telegram.hs:244:13:
No instance for (FromJSON a0) arising from a use of ‘decode’
The type variable ‘a0’ is ambiguous
Relevant bindings include
res :: Maybe a0 (bound at Nightwatch/Telegram.hs:244:7)
Note: there are several potential instances:
instance FromJSON Chat -- Defined at Nightwatch/Telegram.hs:90:10
instance FromJSON Message
-- Defined at Nightwatch/Telegram.hs:106:10
instance FromJSON TelegramResponse
-- Defined at Nightwatch/Telegram.hs:122:10
...plus two others
In the expression: decode msg
In an equation for ‘res’: res = decode msg
In the expression:
do { msg <- WS.receiveData conn;
let res = decode msg;
let v = flip parseMaybe res $ ...;
putStrLn (show v);
.... }
Nightwatch/Telegram.hs:246:44:
Couldn't match type ‘Maybe a0’
with ‘unordered-containers-0.2.5.1:Data.HashMap.Base.HashMap
Text Value’
Expected type: Object
Actual type: Maybe a0
Relevant bindings include
o :: Maybe a0 (bound at Nightwatch/Telegram.hs:245:34)
res :: Maybe a0 (bound at Nightwatch/Telegram.hs:244:7)
In the first argument of ‘(.:)’, namely ‘o’
In a stmt of a 'do' block: r <- o .: "result"
我基本上是在尝试复制 https://hackage.haskell.org/package/aeson-0.10.0.0/docs/Data-Aeson.html
中给出的 "Working with the AST" 示例感谢 Cale 在 #haskell 这里是工作代码:
aria2WebsocketReceiver :: WS.Connection -> IO ()
aria2WebsocketReceiver conn = do
msg <- WS.receiveData conn
let v = do res <- decode msg
flip parseMaybe res $ \o -> do
r <- o .: "result"
version <- r .: "version"
return $ "version=" ++ (version :: String)
putStrLn (show v)
aria2WebsocketReceiver conn
之前的代码存在三个问题:
decode msg
的类型是Maybe
,需要在单独的do
块中。- 由于
{-# LANGUAGE OverloadedStrings #-}
编译器无法推断version
的类型,因此出现(version :: String)
提示。 - 同样,
enabledFeatures
和id_
被赋值但没有在任何地方使用,这在类型推断中引起了更多问题。