Haskell 让ToJSON使用Show实例
如果我的数据类型如下所示:Haskell 让ToJSON使用Show实例,haskell,aeson,Haskell,Aeson,如果我的数据类型如下所示: data SumType = ABC | DEF deriving (Generic, ToJSON) data MyType = MyType {field1 :: String, field2 :: SumType} deriving (Generic, ToJSON) 上面生成的JSON看起来像:{“field1”:“blah”,“field2”:“ABC”} 实际上,MyType是一个相当复杂的类型,我想保持ToJSON的派生,但只想调整一个字段来使用sh
data SumType = ABC | DEF deriving (Generic, ToJSON)
data MyType = MyType {field1 :: String, field2 :: SumType} deriving (Generic, ToJSON)
上面生成的JSON看起来像:{“field1”:“blah”,“field2”:“ABC”}
实际上,MyType
是一个相当复杂的类型,我想保持ToJSON
的派生,但只想调整一个字段来使用show实例
instance Show SumType where
show ABC = "abc-blah"
show DEF = "def-xyz"
不幸的是,上面的Show
实例没有被ToJSON
获取(我不知道它是否应该被获取)。对于SumType
,手动滚动ToJSON
似乎不起作用,因为它需要一个键值对(可能还有其他方法吗?)。换句话说,JSON类似于:{“field1”:“blah”,“field2”:{“field3”:“ABC”}
——我只想改变值字符串化的方式,而不是在那里创建新对象
关于如何在不为MyType
手动创建ToJSON
的情况下更改SumType
的输出字符串,有什么建议吗?所以输出是{“field1”:“blah”,“field2”:“abc blah”}
谢谢 我看不出为
SumType
定义ToJSON
实例有什么问题。您可以通过以下方式执行此操作:
import Data.Aeson(ToJSON(toJSON), Value(String))
import Data.Text(pack)
instance ToJSON SumType where
toJSON = String . pack . show
或者,如果您想对ToJSON
使用其他字符串,而不是Show
:
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson(ToJSON(toJSON), Value(String))
instance ToJSON SumType where
toJSON ABC = String "ABC for JSON"
toJSON DEF = String "DEF for JSON"
现在Haskell将把SumType
编码为JSON字符串:
Prelude Data.Aeson> encode ABC
"\"ABC for JSON\""
Prelude Data.Aeson> encode DEF
"\"DEF for JSON\""
您可以对FromJSON
执行相同的操作,将JSON字符串解析回SumType
对象:
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson(FromJSON(parseJSON), withText)
instance FromJSON SumType where
parseJSON = withText "SumType" f
where f "ABC for JSON" = return ABC
f "DEF for JSON" = return DEF
f _ = fail "Can not understand what you say!"
如果我们随后解析回JSON字符串,我们会得到:
Prelude Data.Aeson> decode "\"ABC for JSON\"" :: Maybe SumType
Just ABC
Prelude Data.Aeson> decode "\"DEF for JSON\"" :: Maybe SumType
Just DEF
Prelude Data.Aeson> decode "\"other JSON string\"" :: Maybe SumType
Nothing
Prelude Data.Aeson> decode "{}" :: Maybe SumType
Nothing
因此,如果我们不解码遵循我们定义的模式之一的JSON字符串,解析将失败。如果我们不提供JSON字符串,例如一个空JSON对象,也会发生同样的情况
附加注释:
SumType
有两个值,所以您还可以使用JSON布尔值对这些值进行编码ABC
,将整数用于DEF
。
尽管我建议在有充分理由之前不要这样做
(例如,ABC
仅携带字符串,而DEF
仅携带一个字符串。)
整数)为
SumType
创建ToJSON
有什么问题?您可以使用Show-SumType
@WillemVanOnsem中的定义,我认为ToJSON
只接受对象。我没有意识到我可以只返回一个字符串。如果你把你的回答写在答案里,我可以接受。传递给with text
的“SumType”
做什么?以其他方式解析时是否更改失败消息?这可能是一个很好的证明。