如何使用模板 Haskell、Aeson 和类型族自动派生 FromJSON

How to auto derive FromJSON using Template Haskell, Aeson, and type families

我想使用模板 haskell 自动生成 ToJSON (Bar Baz) 或 FromJSON (Bar Baz) 实例。 deriveJSON 是 Options -> Name -> Q [Dec] 类型 当类型带参数时如何构造 Name 类型?

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}

import Data.Aeson
import Data.Aeson.TH

data Baz = Baz String

class Foo a where
  data Bar a :: *


instance Foo Baz where
  data Bar Baz = ExampleRecord { exampleField1 :: String
                               , exampleField2 :: String
                               }
data Biz = Biz String

instance Foo Biz where
  data Bar Biz = ExampleBizRecord1 { biz1 :: String } 
               | ExampleBizRecord2 { biz2 :: String }

type BarBaz = Bar Baz

-- doesn't work
deriveJSON defaultOptions (''Bar ''Baz)
deriveJSON defaultOptions mkName "Bar Baz"

-- Creates the Name but not supported by Data.Aeson.TH
derive JSON defaultOptions ''BarBaz

当Foo以类型为参数时,如何使用deriveJSON?

如果你尝试 "obvious" 它不会起作用,但 TH 错误给出了一个有用的提示:

Exception when trying to run compile-time code:
  Data.Aeson.TH.withType: Cannot use a data family name. Use a data family instance constructor instead.
Code: deriveJSON defaultOptions ''Bar

按照建议进行操作似乎有效:

deriveJSON defaultOptions 'ExampleRecord 

给你一个 instance {From/To}JSON (Bar Baz).


同样的事情适用于更新示例。只需使用 任何一个 构造函数名称:

data Biz = Biz String

instance Foo Biz where
  data Bar Biz = ExampleBizRecord1 { biz1 :: String } 
               | ExampleBizRecord2 { biz2 :: String }

deriveJSON defaultOptions 'ExampleBizRecord1 
-- XOR 
deriveJSON defaultOptions 'ExampleBizRecord2