yesod cast" responseBody"到haskell类型

时间:2018-06-05 18:05:51

标签: haskell yesod

以下代码在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的

1 个答案:

答案 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"})