Haskell Aeson Restructures Generic Parsing

I have a style JSON request

{"command":"get","params":{"something":"something else"}} 

and this code snippet from Yesod book

 {-# LANGUAGE OverloadedStrings #-} 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) main :: IO () main = run 3000 app app :: Application app req = handle invalidJson $ do value <- requestBody req $$ sinkParser json newValue <- liftIO $ modValue 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. modValue :: Value -> IO Value modValue (Object o) | -- key "command" corresponds to value "get" | otherwise = fail "Invalid command" 

But I can’t turn my head around how I will destroy the created Value data structure. How can I get key values, etc. I understand that I can deal with a clearly defined data structure, but this can lead to other problems in my use case.

In modValue I added a comment where I cannot figure out what to put. I tried to treat it as a map, since it is implemented inside Aeson, but it obviously does not print a check.

EDIT:

Adding Data.HashMap to import and use a string

  | M.lookup "command" o == Just "get" = return $ object [("result" .= (String "YAY"))] 

contains the following error message.

 main.hs:39:26: Couldn't match expected type `M.Map k0 a0' with actual type `aeson-0.6.0.2:Data.Aeson.Types.Internal.Object' In the second argument of `M.lookup', namely `o' In the first argument of `(==)', namely `M.lookup "command" o' In the expression: M.lookup "command" o == Just "get" 

EDIT2:

Sudden hunch, I found an error message that I received earlier involving "unordered containers". This is the package that Aeson uses. But I realized that I also installed the hashmap of the package, which is imported as Data.HashMap. Hashmaps from unordered containers are imported as Data.HashMap.Strict or Lazy!

Changing the line import qualified Data.HashMap as M to import qualified Data.HashMap.Strict as M is still fixed. Now this answer works!

+4
source share
1 answer

Since the aeson JSON object is a Hashmap , you can use Hasmap , in this case lookup .

 import qualified Data.HashMap.Strict as M M.lookup "command" o == Just "get" 
+5
source

Source: https://habr.com/ru/post/1444778/


All Articles