在Haskell中使用JSON来序列化记录

fri*_*rio 4 json haskell

我一直在研究一个非常小的程序,以获取有关Half Life 2服务器的详细信息(使用 protocol-srcds库).工作流程非常简单; 它从文件中获取服务器列表,查询每个服务器,并将输出写入另一个文件(由PHP脚本读取以供显示,因为我与vBulletin绑定).如果它是用SQL或其他东西完成的话会很好,但看到我还在学习,现在这已经太过分了!

无论如何,我的问题涉及序列化,即序列化为JSON.现在,我已经写了一个杂乱无章的帮助函数jsonify,这样:

jsonify (Just (SRCDS.GameServerInfo serverVersion
                           serverName   
                           serverMap    
                           serverMod    
                           serverModDesc
                           serverAppId  
                           serverPlayers
                           serverMaxPlayers 
                           serverBots
                           serverType
                           serverOS  
                           serverPassword
                           serverSecure  
                           serverGameVersioning)) = 
                            toJSObject [ ("serverName", serverName)
                                       , ("serverMap", serverMap)
                                       , ("serverPlayers", show serverPlayers)
                                       , ("serverMaxPlayers", show serverMaxPlayers) ]
Run Code Online (Sandbox Code Playgroud)

(我正在使用Text.JSON包裹).这显然不太理想.但是,在这个阶段,我不明白使用实例为记录定义序列化程序,而我这样做的尝试在类型系统中遇到了挫败感.

请问有人请指导我完成"正确"的做法吗?我如何定义instance序列化记录?我应该在instance(showJSON?)中使用哪些函数.

在此先感谢您的帮助.

hvr*_*hvr 6

您可能想要考虑使用,Data.Aeson而不是可能被视为继承者Text.JSON.

随着aeson你定义单独的实例进行序列化/反序列化(与Text.JSON你,即使你只需要一个定义两个方向,否则编译会惹恼你-除非你沉默的警告不知),并提供了一些运营商进行界定一个实例比较紧凑,例如来自@ hammar的答案的例子可以写得稍微有点吵,如下面的aesonAPI 所示:

instance ToJSON SRCDS.GameServerInfo where
    toJSON (SRCDS.GameServerInfo {..}) = object
        [ "serverName"       .= serverName
        , "serverMap"        .= serverMap
        , "serverPlayers"    .= serverPlayers
        , "serverMaxPlayers" .= serverMaxPlayers
        ]
Run Code Online (Sandbox Code Playgroud)