haskell - 如何为具有多个构造函数的数据类型编写 ToJSON/FromJSON 实例?

标签 haskell

我见过的每个例子 ToJSONFromJSON用于具有单个构造函数的数据类型,如下所示:

data RewindConfig = RConfig JobID Phase
                      deriving Show

instance FromJSON RewindConfig where
  parseJSON (Object o) = RConfig
    <$> o .: "JobID"
    <*> o .: "Phase"
  parseJSON _ = fail "invalid RewindConfig"

我想我会看看 Aeson 如何为具有多个构造函数的类型创建实例,例如 Either :
instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
   parseJSON (Object (H.toList -> [(key, value)]))
        | key == left  = Left  <$> parseJSON value
        | key == right = Right <$> parseJSON value
   parseJSON _        = fail ""

parseJSON 中的模式匹配让我困惑,我不明白 (H.toList -> [(key, value)]) 发生了什么| .

我要为其创建实例的数据类型如下所示:
data Foo = Bar String
         | Baz String
         | Bin String

我确实想到做一些我知道如何实现的事情
data Foo = (Maybe Bar) (Maybe Baz) (Maybe Bin)

但这似乎并不令人满意。有人能帮我解释一下 Either 的情况吗?例如,也许会给我一些关于 Foo 的 To/From 实例的指导。 ?

更新:我认为 Aeson 为 Maybe 实现的实例更清晰,并告诉我我需要知道什么才能满足我的需求。不过,我想知道 Either 发生了什么事情.

最佳答案

图案(Object (H.toList -> [(key, value)]))被称为 view pattern .你可以把它读成这样:

parseJSon (Object o) = case H.toList o of
    [(key, value)]
        | key == left  -> Left  <$> parseJSON value
        | key == right -> Right <$> parseJSON value

它实际上略有不同,因为以上将始终提交模式 Object o当收到 Object ,而 View 模式仅在“匹配 Object o 模式”和“H.toList o 匹配 [(key, value)] 模式”条件成立时才会提交,但对于本示例而言,这无关紧要。

关于haskell - 如何为具有多个构造函数的数据类型编写 ToJSON/FromJSON 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10339462/

相关文章:

haskell - StateT 与 ReaderT IORef 的异常处理

haskell - 如何在 WinGHCi 中查看当前工作目录

haskell - 在 react 香蕉中进行测试

haskell - 状态 Monad 示例问题

haskell - 为什么decodeFile会抛出 "not enough bytes"错误?

haskell - 为什么下面的类型构造函数比数据构造函数接受更少的参数?

haskell - 在 cygwin 中安装包 wreq 时出错

haskell - 是否有用于编译时检查的示例值以及它们应该在代码中的什么位置?

haskell - 如何在 haskell 中为数据类型创建 Read 实例

haskell - 为什么嵌套永远泄漏内存?