我有一个 API,它以以下形式返回 JSON 结果:
{
"data": [1, 2, 3]
}
该data
字段可以是两个不同记录的编码,如下所示:
newtype ResultsTypeA = ResultsTypeA [ResultTypeA]
newtype ResultsTypeB = ResultsTypeB [ResultTypeB]
当我从 Haskell 查询这个 API 时,我提前知道我是在处理 aResultsTypeA
还是 a ResultsTypeB
,因为我在查询中明确要求它。
我苦苦挣扎的部分是 AesonToJSON
和FromJSON
实例。由于这两种结果类型A
最终B
都是 的列表Int
,因此我不能在 中使用模式匹配器FromJSON
,因为在这两种情况下我只能匹配 a [Int]
。
这就是为什么我想到做以下事情:
newType ApiResponse a =
ApiResponse {
data :: a
}
newtype ResultsTypeA = ResultsTypeA [ResultTypeA]
newtype ResultsTypeB = ResultsTypeB [ResultTypeB]
但是,我无法理解如何为上述内容编写ToJSON
和FromJSON
实例,因为现在ApiResponse
有一个类型参数,并且在 Aeson 文档中似乎没有一个地方可以解释如何使用涉及的类型参数派生这些实例.
另一种避免类型参数的替代方法如下:
newtype Results =
ResultsTypeA [ResultTypeA]
| ResultsTypeB [ResultTypeB]
newtype ApiResponse =
ApiResponse {
data :: Results
}
在这种情况下,这ToJSON
很简单:
instance ToJSON ApiResponse where
toJSON = genericToJSON $ defaultOptions
但是这FromJSON
让我们回到了无法在结果类型A
和B
...之间做出决定的问题。
我也有可能完全做错了,还有第三个选项我看不到。
- 带有类型参数的
FromJSON
/ToJSON
实例会是什么样子ApiResponse
? - 有没有更好的替代方案与上面公开的任何东西完全不同来解决这个问题?