您将如何实现这种Sum类型的FromJson?
data CommandRequest = CreateWorkspace {commandId :: UUID , workspaceId ::UUID }
| IntroduceIdea {commandId :: UUID , workspaceId ::UUID , ideaContent :: String}
instance ToJSON CommandRequest where
toJSON (CreateWorkspace commandId workspaceId) = object [
"commandId" .= commandId,
"workspaceId" .= workspaceId,
"commandName" .= pack "createWorkspace"]
toJSON (IntroduceIdea commandId workspaceId ideaContent) = object [
"commandId" .= commandId,
"workspaceId" .= workspaceId,
"commandName" .= pack "introduceIdea",
"ideaContent" .= ideaContent
]
instance FromJSON CommandRequest where ... ?
因此,基于commandName字段commandName,我将能够重新构建命令。
更新:在你们的帮助下,结果如下:
instance FromJSON CommandRequest where
parseJSON (Object jsonObject) = do
commandName <- jsonObject .: "commandName"
case commandName of
Just (String "createWorkspace") -> CreateWorkspace
<$> jsonObject .: "commandId"
<*> jsonObject .: "workspaceId"
Just (String "introduceIdea") -> IntroduceIdea
<$> jsonObject .: "commandId"
<*> jsonObject .: "workspaceId"
<*> jsonObject .: "ideaContent"
Just (String unknownCommandName) -> error $ "Command unknown : " ++ unpack unknownCommandName
Nothing -> error $ "Command name not provided"
答案 0 :(得分:5)
只需通过commandName
看一下(.:)
,然后决定要做什么。所以:
instance FromJSON CommandRequest where
parseJSON (Object o) = do
commandName <- o .: "commandName"
case commandName :: String of
"createWorkspace" -> liftA2 CreateWorkspace (o .: "commandId") (o .: "workspaceId")
"introduceIdea" -> liftA3 IntroduceIdea (o .: "commandId") (o .: "workspaceId") (o .: "ideaContent")
_ -> typeMismatch "wrongo" (Object o)
parseJSON v = typeMismatch "double wrongo" v