1

最新版本的 Data.Aeson 改变了 ToJSON 和 FromJSON 适用于简单类型的方式,例如:

data Permission = Read | Write

它曾经是通用调用:

instance ToJSON Permission where 

...将创建看起来像 {"Read":[]} 或 {"Write":[]} 的 JSON。

但现在它创建了: {tag:"Read",contents:"[]"}

这是有道理的,但会破坏我编写的代码。我手工编写了一个 toJSON 部分以提供正确的外观,但编写 fromJSON 让我感到困惑。

有任何想法吗?

谢谢

4

2 回答 2

2

allNullaryToStringTag您可以控制如何使用field on 对所有 nullary 构造函数的数据类型进行编码Data.Aeson.Options。将其设置为True,它将被简单地编码为字符串。

import Data.Aeson.Types (Options (..), defaultOptions)

data Permission = Read | Write

$(deriveToJSON (defaultOptions {allNullaryToStringTag = True}) ''Permission)

看一下Options定义,它包含其他方便的字段。

于 2013-10-09T14:03:19.920 回答
1

由于Object构造函数中包含的值Data.Aeson.Value只是一个 strict HashMap,我们可以从中提取键并据此做出决定。我试过了,效果很好。

{-# LANGUAGE OverloadedStrings #-}
module StackOverflow where

import Data.Aeson
import Control.Monad
import Data.HashMap.Strict (keys)

data Permission = Read | Write

instance FromJSON Permission where
    parseJSON (Object v) =
        let ks = keys v
        in case ks of
            ["Read"] -> return Read
            ["Write"] -> return Write
            _ -> mzero
    parseJSON _ = mzero

您可以使用decode "{\"Read\": []}" :: Maybe Permission. mzeroin确保如果传入其他内容parseJSON,它只会返回Nothing。由于您似乎只想检查是否有一个密钥与您的两个权限之一匹配,因此这非常简单,并且将正确返回Nothing所有其他输入。

于 2013-09-13T20:48:58.470 回答