derive-topdown
Derive type class instances
https://github.com/HaskellZhangSong/derive-topdown#readme
LTS Haskell 23.1: | 0.1.0.0 |
Stackage Nightly 2024-12-25: | 0.1.0.0 |
Latest on Hackage: | 0.1.0.0 |
derive-topdown-0.1.0.0@sha256:04c7327d06318a88ec676aa2fbac22de5393d442910d3c2f00e02d8d0010263e,2791
Module documentation for 0.1.0.0
derive-topdown
This is a Haskell project which will derive type class instances from top for a composite data type.
1. Standalone deriving
There are functions named deriving_
, derivings
, derivingss
. Please see the API for their types.
{-# LANGUAGE StandaloneDeriving,
ConstraintKinds,
UndecidableInstances,
GADTs,
TemplateHaskell,
DeriveGeneric #-}
{-# OPTIONS_GHC -ddump-splices #-}
import Data.Derive.TopDown
import GHC.Generics
import Data.Binary
import Data.Aeson
import Data.Aeson.TH
data Gender = Male | Female
type Age = Int
data Person a = P {name :: String , age :: Int, gender :: Gender}
data Department a = D {dname :: String ,
head :: Person a,
staff :: [Person a]}
data Company a = C {cname :: String,
departments :: [Department a]}
derivings [''Eq, ''Ord, ''Generic] ''Company
You will get:
derivings [''Eq, ''Ord, ''Generic] ''Company
======>
deriving instance Eq Gender
deriving instance Eq (Person a_acKV)
deriving instance Eq a_acKU => Eq (Department a_acKU)
deriving instance Eq a_acKT => Eq (Company a_acKT)
deriving instance Ord Gender
deriving instance Ord (Person a_acKV)
deriving instance Ord a_acKU => Ord (Department a_acKU)
deriving instance Ord a_acKT => Ord (Company a_acKT)
deriving instance Generic Gender
deriving instance Generic (Person a_acKV)
deriving instance Generic (Department a_acKU)
deriving instance Generic (Company a_acKT)
2. Empty Instances generation
For empty class instances deriving, instance_
, instances
, instancess
are provided. We can use it in this way.
instances [''Binary] ''Company
======>
instance Binary Gender
instance Binary (Person a_af50)
instance Binary a_af4Z => Binary (Department a_af4Z)
instance Binary a_af4Y => Binary (Company a_af4Y)
3. Usage with Template Haskell
For generating instances with a template Haskell function, derivingTH
, derivingTHs
and derivingTHss
can be used:
derivingTHs
[(''ToJSON, deriveToJSON defaultOptions),
(''FromJSON, deriveFromJSON defaultOptions)]
''Company
======>
instance ToJSON Gender where
toJSON
= \ value_amQG
-> case value_amQG of {
Male -> String (text-1.2.2.2:Data.Text.pack "Male")
Female -> String (text-1.2.2.2:Data.Text.pack "Female") }
toEncoding
= \ value_amQH
-> case value_amQH of {
Male
-> Data.Aeson.Encoding.Internal.text
(text-1.2.2.2:Data.Text.pack "Male")
Female
-> Data.Aeson.Encoding.Internal.text
(text-1.2.2.2:Data.Text.pack "Female") }
instance ToJSON a_amqg => ToJSON (Person a_amqg) where
toJSON
= \ value_amQy
...
...
You can use this this function with derive
package. However, it seems that this package is broken with GHC >= 802.
4. Deriving the superclasses
Data.Derive.Superclass
provides deriving_superclasses
, strategy_deriving_superclasses
and newtype_deriving_superclasses, gnds can be used to derive class instance and its superclass instances.
For example:
data A = A
deriving_superclasses ''Ord ''A
You wil get:
deriving_superclasses ''Ord ''A
======>
deriving instance Ord A
deriving instance Eq A
Mutual recursive type decalrations need to derive superclass together as the following:
fmap concat (sequence [(deriving_superclasses ''Ord ''T2), (deriving_superclasses ''Ord ''T3)])
In the code above, T2 and T3 are mutual recursive data types.
5. Deriving with strategies in GHC 8.2
If you want to specify the strategy for deriving mechanism then strategy_deriving
, strategy_derivings
and strategy_derivingss
can be used.
The 3 strategies for deriving StockStrategy
,AnyclassStrategy
,NewtypeStrategy
are exposed when you import TopDown
. They can be written as stock
, anyclass
as the default grammar. For newtype
, you can write it as newtype_
since there is a clison with newtype
for data declaration. Please see DerivingStrategies
Note
Derive with breaks
The deriving process might be interrupted by a given list of type names. The generation process will stop on those give names. Please see the test case.
NOTE: About deriving instances of Typeable
There is a bug with isInstance
function when working with Typeable class. See ticket #11251
. So there might be problems if you really want to derive Typeable
class. However, this bug should not affect you too much here since GHC now has AutoDeriveTypeable
extension, which means you should never derive Typeable
manually.
NOTE: You cannot derive a type synonym.
derive-topdown
will not work with -XTypeSynonymInstances
language extension. The top node in the data declaration tree has to be a data or newtype.
More discussion about derive-topdown
, please see ticket #10607
Changes
derive-topdown
derive-topdown-0.1.0.0
0.1.0.0
- Almost a reimplementation the deriving and instance generation functions.
- Implement class context generation. Now only necessary context type will be generated.
- This version only compatible for ghc-8.6 to ghc-9.10. ghc-8.4 and ghc-8.2 can build but not able to run test cases.
derive-topdown-0.0.3.0
0.0.3.0
- Adapt to GHC 9.0.
derive-topdown-0.0.2.1
0.0.2.1
- Remove unnecessary dependencies for testing.
derive-topdown-0.0.2.0
0.0.2.0
- Add deriving superclass functions. When you want to derive a class instance, not necessary to derive all its superclasses.
derive-topdown-0.0.1.0
0.0.1.0
- Imporve error message.Will print the types list when type is not data or newtype defined.
derive-topdown-0.0.0.9
0.0.0.9
- Changed API for
strategy_derivng(s)
. Deriving strategy should be specified first as the default grammar ofderiving
. - Provided
deriving_with_breaks
function so that one can specify the types that prevent further standalone deriving declarations from generating process. This is mainly forGeneric
class. See the test of derivingGeneric
forHsModule
. - Fixed Strategy deriving problem. Deriving with NewtypeStrategy on data type defined by
data
keyword will be ignored. - Fixed problem with class context generation for phantom types. Phantom types will not be in the context now.
- Fixed
ArrowT
problem. It should be not a type variable and should appear in the context. - Handled data constructor which contains explicit
forall
. - Added test. It generates class instances for data types in
template-haskell
andhaskell-src
.
- Changed API for
derive-topdown-0.0.0.7
0.0.0.7
is a more carefully implemented version of derive-topdown. All APIs are totally changed compared with 0.0.0.2. Originally it did not work with types that contain type synonyms and polymorphic types. It can work for most common cases in this version now.
derive-topdown-0.0.0.2
- Fixed some cabal file and API problems.
derive-topdown-0.0.0.1
- This is only an experimental implementation for deriving class instances from top to bottom. There is a lot of deficiencies.