我想以 JSON 格式输出我的应用程序的日志,但是有一些普遍存在的数据类型ToJSON
没有定义实例 - 最值得注意SomeException
的是整个Exception
类型的层次结构。
我有两个选择:
ToJSON
在我的应用程序中为此类数据类型定义实例- 编写我自己的类型类,比如
ToJsonLogs
,并使其ToJSON
尽可能地重用实例。
第一个是“阻力最小”的路径,但它还有其他含义。由于类型类实例本质上是全局的,我最终可能会定义ToJSON
破坏某些东西的实例。此外,对于相同的数据结构,我可能希望 API 中的 JSON 与日志中的 JSON 不同(例如,清理密钥、授权令牌和其他敏感数据或截断非常长的文本字段)。
这个问题是关于探索第二种选择的。我该如何做以下事情:
class ToJsonLogs a where
toJsonLogs :: a -> Aeson.Value
default toJsonLogs :: (ToJSON a) => a -> Aeson.Value
toJsonLogs = toJSON
instance ToJsonLogs SomeException where
toJsonLogs = toJSON . displayException
我尝试了上述想法,但它在第一步本身就失败了。这是一个示例数据结构:
data SyncResult = SyncResult
{ resAborted :: !Bool
, resSuccessful :: !Int
, resFailed :: ![(Int, SomeException)]
} deriving (Show)
ToJsonLogs
如果不首先推导ToJSON
整个数据结构,我就无法推导。由于 的推导ToJSON
失败SomeException
。因此,这个问题的标题。
我什至试着和泛型鬼混,但像往常一样,又被卡住了。