(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 中给出的“使用 AST”示例
最佳答案
感谢 #haskell 的 Cale,这是工作代码:
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
block 内。- 由于
{-# LANGUAGE OverloadedStrings #-}
,编译器无法推断version
的类型,因此(version::字符串)
提示。 - 同样,
enabledFeatures
和id_
已被分配但未在任何地方使用,这导致了类型推断中的更多问题。
关于haskell - 如何在不声明单个类型的情况下使用 Aeson 解析 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35077554/