(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"
我基本上试图复制&#34;使用AST&#34;在https://hackage.haskell.org/package/aeson-0.10.0.0/docs/Data-Aeson.html
给出的示例答案 0 :(得分:6)
感谢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_
被分配但未在任何地方使用,这导致了类型推断中的更多问题。