使用 Aeson 对 Json 中的基本求和类型进行序列化
Serialization of a basic sum type in Json with Aeson
type GoalDescription = Text
data GoalStatus = Created | Accomplished | InProgress | GivenUp deriving (Show , Eq , Generic )
data Goal = Goal {workspaceId ::WorkspaceId , goalId :: GoalId , description :: GoalDescription , status :: GoalStatus} deriving (Show , Eq , Generic )
instance ToJSON Goal where
toJSON (Goal {workspaceId, goalId ,description,status } ) = object [
"workspaceId" .= workspaceId,
"goalId" .= goalId,
"description" .= description,
"status" .= status]
instance FromJSON Goal where
parseJSON (Object jsonObject) = Goal <$> jsonObject .: "workspaceId" <*> jsonObject .: "goalId" <*> jsonObject .: "description" <*> jsonObject .: "status"
parseJSON _ = error $ "Json format not expected"
我想以这种方式实现 GoalStatus 的 FromJSON 和 ToJSON:Goal {.. status:"accomplished"}
或 Goal {.. status:"inProgress"}
等等...不知何故我不知道如何实现这些类型 类 没有有一个键 -> 值结构... GoalStatus
应该只转换成 String Text
没有附加到值的键..
我有这个临时解决方案,我不得不添加一个名为 "value" 的不必要的密钥:
instance ToJSON GoalStatus where
toJSON (Created) = object ["value" .= String "created"]
toJSON (InProgress) = object ["value" .= String "inProgress"]
toJSON (Accomplished) = object ["value" .= String "accomplished"]
toJSON (GivenUp) = object ["value" .= String "GivenUp"]
instance FromJSON GoalStatus where
parseJSON (Object o) = do
value <- o .: "value"
case value of
String status | (unpack status) == "created" -> return Created
String status | (unpack status) == "inProgress" -> return InProgress
String status | (unpack status) == "accomplished" -> return Accomplished
String status | (unpack status) == "accomplished" -> return GivenUp
_ -> error $ "Json format not expected"
parseJSON _ = error $ "Json format not expected"
String !Text
是 Value
的构造函数,object
具有类型签名 [Pair] -> Value
,其中 Pair
是 (Text, Value)
。您可以使用 String
在 ToJSON
中生成 Value
,然后在 FromJSON
.
中解析时匹配 String
的特定形状
instance ToJSON GoalStatus where
toJSON (Created) = String "created"
toJSON (InProgress) = String "inProgress"
toJSON (Accomplished) = String "accomplished"
toJSON (GivenUp) = String "givenUp"
instance FromJSON GoalStatus where
parseJSON (String s) = case unpack s of
"created" -> return Created
"inProgress" -> return InProgress
"accomplished" -> return Accomplished
"givenUp" -> return GivenUp
_ -> error $ "Json format not expected"
parseJSON _ = error $ "Json format not expected"
我不确定我是否理解问题。这是一个包含通用派生实现的完整文件:
{-# LANGUAGE DeriveGeneric #-}
module Q54178405 where
import Data.Text
import Data.Aeson
import GHC.Generics
type WorkspaceId = Int
type GoalId = Int
type GoalDescription = Text
data GoalStatus =
Created | Accomplished | InProgress | GivenUp deriving (Show, Eq, Generic)
instance ToJSON GoalStatus
instance FromJSON GoalStatus
data Goal = Goal {
workspaceId ::WorkspaceId
, goalId :: GoalId
, description :: GoalDescription
, status :: GoalStatus}
deriving (Show, Eq, Generic)
instance ToJSON Goal
instance FromJSON Goal
以下是它在 GHCi 中的表现:
*Q54178405 Q54178405> encode $ Goal 42 1337 "foo" Accomplished
"{\"status\":\"Accomplished\",\"goalId\":1337,\"workspaceId\":42,\"description\":\"foo\"}"
*Q54178405 Q54178405> encode $ Goal 42 1337 "foo" GivenUp
"{\"status\":\"GivenUp\",\"goalId\":1337,\"workspaceId\":42,\"description\":\"foo\"}"
这不就是你想要的吗?
实例往返也是:
*Q54178405 Q54178405> decode $ encode $ Goal 42 1337 "foo" GivenUp :: Maybe Goal
Just (Goal {workspaceId = 42, goalId = 1337, description = "foo", status = GivenUp})
如果这不是您想要的,它对于一些具有所需输出的输入的明确示例会很有用。
type GoalDescription = Text
data GoalStatus = Created | Accomplished | InProgress | GivenUp deriving (Show , Eq , Generic )
data Goal = Goal {workspaceId ::WorkspaceId , goalId :: GoalId , description :: GoalDescription , status :: GoalStatus} deriving (Show , Eq , Generic )
instance ToJSON Goal where
toJSON (Goal {workspaceId, goalId ,description,status } ) = object [
"workspaceId" .= workspaceId,
"goalId" .= goalId,
"description" .= description,
"status" .= status]
instance FromJSON Goal where
parseJSON (Object jsonObject) = Goal <$> jsonObject .: "workspaceId" <*> jsonObject .: "goalId" <*> jsonObject .: "description" <*> jsonObject .: "status"
parseJSON _ = error $ "Json format not expected"
我想以这种方式实现 GoalStatus 的 FromJSON 和 ToJSON:Goal {.. status:"accomplished"}
或 Goal {.. status:"inProgress"}
等等...不知何故我不知道如何实现这些类型 类 没有有一个键 -> 值结构... GoalStatus
应该只转换成 String Text
没有附加到值的键..
我有这个临时解决方案,我不得不添加一个名为 "value" 的不必要的密钥:
instance ToJSON GoalStatus where
toJSON (Created) = object ["value" .= String "created"]
toJSON (InProgress) = object ["value" .= String "inProgress"]
toJSON (Accomplished) = object ["value" .= String "accomplished"]
toJSON (GivenUp) = object ["value" .= String "GivenUp"]
instance FromJSON GoalStatus where
parseJSON (Object o) = do
value <- o .: "value"
case value of
String status | (unpack status) == "created" -> return Created
String status | (unpack status) == "inProgress" -> return InProgress
String status | (unpack status) == "accomplished" -> return Accomplished
String status | (unpack status) == "accomplished" -> return GivenUp
_ -> error $ "Json format not expected"
parseJSON _ = error $ "Json format not expected"
String !Text
是 Value
的构造函数,object
具有类型签名 [Pair] -> Value
,其中 Pair
是 (Text, Value)
。您可以使用 String
在 ToJSON
中生成 Value
,然后在 FromJSON
.
String
的特定形状
instance ToJSON GoalStatus where
toJSON (Created) = String "created"
toJSON (InProgress) = String "inProgress"
toJSON (Accomplished) = String "accomplished"
toJSON (GivenUp) = String "givenUp"
instance FromJSON GoalStatus where
parseJSON (String s) = case unpack s of
"created" -> return Created
"inProgress" -> return InProgress
"accomplished" -> return Accomplished
"givenUp" -> return GivenUp
_ -> error $ "Json format not expected"
parseJSON _ = error $ "Json format not expected"
我不确定我是否理解问题。这是一个包含通用派生实现的完整文件:
{-# LANGUAGE DeriveGeneric #-}
module Q54178405 where
import Data.Text
import Data.Aeson
import GHC.Generics
type WorkspaceId = Int
type GoalId = Int
type GoalDescription = Text
data GoalStatus =
Created | Accomplished | InProgress | GivenUp deriving (Show, Eq, Generic)
instance ToJSON GoalStatus
instance FromJSON GoalStatus
data Goal = Goal {
workspaceId ::WorkspaceId
, goalId :: GoalId
, description :: GoalDescription
, status :: GoalStatus}
deriving (Show, Eq, Generic)
instance ToJSON Goal
instance FromJSON Goal
以下是它在 GHCi 中的表现:
*Q54178405 Q54178405> encode $ Goal 42 1337 "foo" Accomplished
"{\"status\":\"Accomplished\",\"goalId\":1337,\"workspaceId\":42,\"description\":\"foo\"}"
*Q54178405 Q54178405> encode $ Goal 42 1337 "foo" GivenUp
"{\"status\":\"GivenUp\",\"goalId\":1337,\"workspaceId\":42,\"description\":\"foo\"}"
这不就是你想要的吗?
实例往返也是:
*Q54178405 Q54178405> decode $ encode $ Goal 42 1337 "foo" GivenUp :: Maybe Goal
Just (Goal {workspaceId = 42, goalId = 1337, description = "foo", status = GivenUp})
如果这不是您想要的,它对于一些具有所需输出的输入的明确示例会很有用。