如何使用Template Haskell,Aeson和type系列自动派生FromJSON

时间:2016-03-14 16:25:29

标签: haskell template-haskell aeson 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?

1 个答案:

答案 0 :(得分:4)

如果您尝试“显而易见”的事情它将无法正常工作,但TH错误提供了一个有用的提示:

GeneratorInput

做什么建议似乎有效:

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)