这似乎是基于泛型的解析的一个已知问题。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)
这样,该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})
更新:如评论中所述,Aeson HEAD 中的 Template Haskell 可以省略空字段,但这还没有在 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 ]