如何创建" ActionCtxT"在Spock?

时间:2017-05-09 15:17:06

标签: haskell haskell-spock

我想从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类型以及所有其他行。或纯粹的价值。那么,如何解决呢?

1 个答案:

答案 0 :(得分:0)

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实例。