我想从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 类型以及所有其他行。或纯值。那么,如何解决呢?
jsonBody' :: (MonadIO m, FromJSON a) => ActionCtxT ctx m a
jsonBody'
为您提供了使用 Aeson FromJSON
实例解析请求正文的方法。
通过将 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 实例。