以下代码在yesod中进行api调用。问题是我如何"演员"结果对象为预定义的haskell类型?
Network.HTTP.Conduit.withManager $ \manager -> do
response <- http req manager
resBody <- responseBody response C.$$+- sinkParser json
liftIO $ putStrLn $ T.pack (show resBody)
示例输出日志
Object (fromList [("val1",Number 1.0),("val2",String "text")])
我用Aeson或fromJSON进行解码的所有尝试都失败了。
非常感谢
Yunis的
答案 0 :(得分:2)
价值来自哪里似乎并不重要。您已经掌握了Aeson.Value
类型的数据,因此您只需要弄清楚如何使用fromJSON成功尝试。
这里有一些代码改编自the FromJSON class
的文档{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Aeson as Aeson
import qualified Data.HashMap.Strict as HashMap
import Data.Aeson ((.:))
import Data.Text (Text)
-- this is the data you already have, which you named resBody
resBody :: Aeson.Value
resBody = Aeson.Object $
HashMap.fromList
[ ("val1", Aeson.Number 1.0)
, ("val2", Aeson.String "text")]
-- Step 1: create a custom Haskell data type to house the data.
-- I named it Coord to match the example code from the link above,
-- but you should probably give it a more meaningful name.
data Coord = Coord { x :: Double, y :: Text }
deriving (Show)
-- Step 2: write a FromJSON instance for your custom data type.
-- In this case, it is almost identical to the example code in the docs.
instance Aeson.FromJSON Coord where
parseJSON = Aeson.withObject "Coord" $ \v -> Coord
<$> v .: "val1"
<*> v .: "val2"
在repl中给它一个旋转
ghci> -- Here's our data
ghci> resBody
Object (fromList [("val1",Number 1.0),("val2",String "text")])
ghci> -- Next, we decode using fromJSON, annotating the result as our desired type
ghci> Aeson.fromJSON resBody :: Aeson.Result Coord
Success (Coord {x = 1.0, y = "text"})