gpt4 book ai didi

haskell - AesonderiveJSON结合管道sinkParser

转载 作者:行者123 更新时间:2023-12-01 02:30:30 25 4
gpt4 key购买 nike

继续我对管道和 aeson 的探索,我将如何使用我自己的数据类型而不是 Value在来自 Yesod book 的这个(稍微修改过的)代码片段中.

{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
import Network.Wai (Response, responseLBS, Application, requestBody)
import Network.HTTP.Types (status200, status400)
import Network.Wai.Handler.Warp (run)
import Data.Aeson.Parser (json)
import Data.Conduit.Attoparsec (sinkParser)
import Control.Monad.IO.Class (liftIO)
import Data.Aeson (Value(..), encode, object, (.=))
import Control.Exception (SomeException)
import Data.ByteString (ByteString)
import Data.Conduit (ResourceT, ($$))
import Control.Exception.Lifted (handle)

import qualified Data.HashMap.Strict as M
import Data.Aeson.TH (deriveJSON)

-- I ADDED THIS

data JSONRequest = JSONRequest {
command :: ByteString,
params :: M.HashMap ByteString ByteString
}

deriveJSON id ''JSONRequest

-- END OF WHAT I ADDED

main :: IO ()
main = run 3000 app

app :: Application
app req = handle invalidJson $ do
value <- requestBody req $$ sinkParser json
newValue <- liftIO $ dispatch value
return $ responseLBS
status200
[("Content-Type", "application/json")]
$ encode newValue

invalidJson :: SomeException -> ResourceT IO Response
invalidJson ex = return $ responseLBS
status400
[("Content-Type", "application/json")]
$ encode $ object
[ ("message" .= show ex)
]

-- Application-specific logic would go here.
dispatch :: Value -> IO Value
dispatch = return

基本上,我想改变 dispatch 的类型到 JSONRequest -> IO JSONRequest。我如何告诉解析器使用我自己的 fromJSON 派生实例?

我尝试只添加一个类型声明,为 json 上的多态返回类型祈祷,但我意识到它严格适用于 Value。

最佳答案

只看类型,难道你只需要fmap您的 fromJSON来自 json 的结果?带有合适的签名 dispatch我们只需要:

-- import Data.Aeson
app :: Application
app req = handle invalidJson $ do
result <- requestBody req $$ sinkParser (fmap fromJSON json)
next_result <- liftIO $ dispatch result
return $ responseLBS status200 [("Content-Type", "application/json")]
$ encode next_result

dispatch :: Result JSONRequest -> IO JSONRequest
dispatch (Error str) = undefined
dispatch (Success jsonreq) = return jsonreq

但也许这样写会更清楚一点:
-- import Data.Aeson
-- import qualified Data.Attoparsec as Atto
toRequest :: Value -> Result JSONRequest
toRequest = fromJSON -- specialized now to your fromJSON

jsonRequestParser :: Atto.Parser (Result JSONRequest)
jsonRequestParser = fmap toRequest json

app :: Application
app req = handle invalidJson $ do
result <- requestBody req $$ sinkParser jsonRequestParser
next_result <- liftIO $ dispatch result
return $ responseLBS status200 [("Content-Type", "application/json")]
$ encode next_result

dispatch :: Result JSONRequest -> IO JSONRequest
dispatch (Error str) = undefined
dispatch (Success jsonreq) = return jsonreq

我离开解析器返回 Result JSONRequest所以 dispatch也在处理错误情况,这可能意味着您需要以某种方式处理异常?

关于haskell - AesonderiveJSON结合管道sinkParser,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13290975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com