I would like to use template haskell to auto generate the ToJSON (Bar Baz), or FromJSON (Bar Baz) instances. the deriveJSON is of type Options -> Name -> Q [Dec]
how to I construct the Name
type when the type takes parameters?
{-# 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
How to use the deriveJSON when Foo takes a type as a parameter?
If you try the "obvious" thing it won't work, but the TH error gives a helpful hint:
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
Doing what is suggests seems to work:
deriveJSON defaultOptions 'ExampleRecord
gets you an instance {From/To}JSON (Bar Baz)
.
The same thing works for the update example. Just use any one constructor name:
data Biz = Biz String
instance Foo Biz where
data Bar Biz = ExampleBizRecord1 { biz1 :: String }
| ExampleBizRecord2 { biz2 :: String }
deriveJSON defaultOptions 'ExampleBizRecord1
-- XOR
deriveJSON defaultOptions 'ExampleBizRecord2