jch*_*chl 3 data-binding json haskell
是否可以使用Text.JSON.Generic包含可选字段的JSON记录类型?我希望如果我宣布Haskell类型为"只是工作" Maybe a,例如:
import Text.JSON.Generic
data Record = Record {
myMandatoryField :: Integer,
myOptionalField :: Maybe Integer
} deriving (Eq, Show, Data, Typeable)
Run Code Online (Sandbox Code Playgroud)
但这不是正确的事情.
如果无法使用可选字段Text.JSON.Generic,是否有可选的Haskell-JSON数据绑定库可以使用可选字段?
这似乎是基于泛型的解析的已知问题.Aeson遇到了同样的问题,维护人员决定弃用该功能,转而采用基于模板Haskell的策略:https://github.com/bos/aeson/issues/118
使用Aeson,您的代码看起来非常相似:
import Data.Aeson
import Data.Aeson.TH
data Record = Record {
myMandatoryField :: Integer,
myOptionalField :: Maybe Integer
} deriving (Eq, Show)
$(deriveJSON id ''Record)
Run Code Online (Sandbox Code Playgroud)
这样,Maybe字段按预期编码和解码:
$ ghci
? :l Main.hs
Ok, modules loaded: Main.
? encode $ Record 5 Nothing
"{\"myOptionalField\":null,\"myMandatoryField\":5}"
? decode it :: Maybe Record
Just (Record {myMandatoryField = 5, myOptionalField = Nothing})
Run Code Online (Sandbox Code Playgroud)
更新:正如评论中所提到的,在Aeson HEAD中,模板Haskell可以使用null-field omission,但是还没有在Hackage上.您今天可以通过手写FromJSON/ ToJSON实例获得该行为:
instance FromJSON Record where
parseJSON = withObject "record" $ \o -> Record
<$> o .: "myMandatoryField"
<*> o .:? "myOptionalField"
instance ToJSON Record where
toJSON (Record manf optf) = object $ catMaybes
[ ("myMandatoryField" .=) <$> pure manf
, ("myOptionalField" .=) <$> optf ]
Run Code Online (Sandbox Code Playgroud)