0

我想从 json 对象中提取一个值。我有这个:

    post "/test" $ do
        a <- jsonBody'
        let b = show (a :: Object) -- works well
        myVal <- (a :: Object) .: "some_key" -- error
        text "test123"

和错误:

• Couldn't match type ‘aeson-1.0.2.1:Data.Aeson.Types.Internal.Parser’
                     with ‘ActionCtxT () (WebStateM () MySession MyAppState)’
      Expected type: ActionCtxT () (WebStateM () MySession MyAppState) a0
        Actual type: aeson-1.0.2.1:Data.Aeson.Types.Internal.Parser a0
    • In a stmt of a 'do' block:
        myVal <- (a :: Aeson.Object) Aeson..: "some_key"

我知道这意味着什么:带有 myVal 的行必须返回 ActionCtxT 类型以及所有其他行。或纯值。因此,如何修复它?

4

1 回答 1

0
jsonBody' :: (MonadIO m, FromJSON a) => ActionCtxT ctx m a

jsonBody'为您提供使用 AesonFromJSON实例解析请求正文的方法。

通过将 JSON 数据映射到自定义数据类型,然后FromJSON为该数据类型提供实例,通常更容易使用 Aeson。

解释您可以在 Aeson 文档中找到的示例,如果您的 JSON 看起来像这样:

 { "name": "Joe", "age": 12 }

然后你可以创建一个数据类型:

data Person = Person {
      name :: Text
    , age  :: Int
    } deriving Show

并手动创建 FromJSON 实例:

{-# LANGUAGE OverloadedStrings #-}

instance FromJSON Person where
    parseJSON (Object v) = Person <$>
                           v .: "name" <*>
                           v .: "age"
    -- A non-Object value is of the wrong type, so fail.
    parseJSON _          = empty

您也可以从您的数据类型中自动派生 FromJSON 实例。

于 2017-05-09T19:58:52.007 回答