TopdownDerive
This code will do standalone deriving along the data type declaration dependencies in Haskell.
Please see https://ghc.haskell.org/trac/ghc/ticket/10607
For example
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# OPTIONS_GHC -ddump-splices #-}
import Data.Derive.TopDown.StandaloneDerive
import qualified GHC.Generics as G
import qualified Data.Binary as B
import qualified Data.Aeson as A
data C a b = A (B a)
data B a = B a | F (D a)
data D b = D b | E b
derivings instances [''Eq, ''G.Generic, ''Ord] ''C
derivings generic_instances [''B.Binary, ''A.FromJSON, ''A.ToJSON] ''C
will give:
derivings instances [''Eq, ''G.Generic, ''Ord] ''C
======>
deriving instance Eq b_acQA => Eq (D b_acQA)
deriving instance Eq a_acQB => Eq (B a_acQB)
deriving instance (Eq a_acQC, Eq b_acQD) => Eq (C a_acQC b_acQD)
deriving instance G.Generic b_acQA => G.Generic (D b_acQA)
deriving instance G.Generic a_acQB => G.Generic (B a_acQB)
deriving instance (G.Generic a_acQC, G.Generic b_acQD) =>
G.Generic (C a_acQC b_acQD)
deriving instance Ord b_acQA => Ord (D b_acQA)
deriving instance Ord a_acQB => Ord (B a_acQB)
deriving instance (Ord a_acQC, Ord b_acQD) => Ord (C a_acQC b_acQD)
D:\Haskell\TopDerive.hs:20:1-70: Splicing declarations
derivings
generic_instances [''B.Binary, ''A.FromJSON, ''A.ToJSON] ''C
======>
deriving instance (B.Binary b_acQA, G.Generic b_acQA) =>
B.Binary (D b_acQA)
deriving instance (B.Binary a_acQB, G.Generic a_acQB) =>
B.Binary (B a_acQB)
deriving instance (B.Binary a_acQC,
B.Binary b_acQD,
G.Generic a_acQC,
G.Generic b_acQD) =>
B.Binary (C a_acQC b_acQD)
deriving instance (A.FromJSON b_acQA, G.Generic b_acQA) =>
A.FromJSON (D b_acQA)
deriving instance (A.FromJSON a_acQB, G.Generic a_acQB) =>
A.FromJSON (B a_acQB)
deriving instance (A.FromJSON a_acQC,
A.FromJSON b_acQD,
G.Generic a_acQC,
G.Generic b_acQD) =>
A.FromJSON (C a_acQC b_acQD)
deriving instance (A.ToJSON b_acQA, G.Generic b_acQA) =>
A.ToJSON (D b_acQA)
deriving instance (A.ToJSON a_acQB, G.Generic a_acQB) =>
A.ToJSON (B a_acQB)
deriving instance (A.ToJSON a_acQC,
A.ToJSON b_acQD,
G.Generic a_acQC,
G.Generic b_acQD) =>
A.ToJSON (C a_acQC b_acQD)
Note: if you want to derive a type class with a default implementation with Generic class, you need to write derivings generic_instances
.
Hope this can save you some work.