packages feed

generic-deriving 1.5.0 → 1.14.7

raw patch · 34 files changed

Files

+ CHANGELOG.md view
@@ -0,0 +1,235 @@+# 1.14.7 [2026.01.03]+* Allow building with GHC 9.14.+* Remove unused `ghc-prim` dependency.++# 1.14.6 [2024.12.05]+* Drop support for GHC 7.10 and earlier.++# 1.14.5 [2023.08.06]+* Support building with `template-haskell-2.21.*` (GHC 9.8).+* The Template Haskell machinery now uses `TemplateHaskellQuotes` when+  building with GHC 8.0+ instead of manually constructing each Template Haskell+  `Name`. A consequence of this is that `generic-deriving` will now build with+  GHC 9.8, as `TemplateHaskellQuotes` abstracts over some internal Template+  Haskell changes introduced in 9.8.++# 1.14.4 [2023.04.30]+* Allow building with GHC backends where `HTYPE_SIG_ATOMIC_T` is not defined,+  such as the WASM backend.+* Place `INLINE [1]` pragmas on `from` and `to` implementations when types+  don't have too many constructors or fields, following the heuristics that GHC+  9.2+ uses for `Generic` deriving.++# 1.14.3 [2023.02.27]+* Support `th-abstraction-0.5.*`.++# 1.14.2 [2022.07.23]+* Fix a bug in which `deriveAll1` could generate ill kinded code when using+  `kindSigOptions=False`, or when using GHC 8.0 or earlier.+* Fix a bug in which `deriveAll1` would reject data types whose last type+  variable has a kind besides `Type` or `k` on GHC 8.2 or later.++# 1.14.1 [2021.08.30]+* Backport the `Generic(1)` instances introduced for tuples (8 through 15) in+  `base-4.16`.+* Make the test suite compile on GHC 9.2 or later.+* Always import `Data.List` qualified to fix the build with recent GHCs.++# 1.14 [2020.09.30]+* Remove instances for `Data.Semigroup.Option`, which is deprecated as of+  `base-4.15.0.0`.+* Allow building with `template-haskell-2.17.0.0` (GHC 9.0).+* Fix a bug in which `deriveAll1` would needlessly reject data types whose last+  type parameter appears as an oversaturated argument to a type family.++# 1.13.1 [2019.11.26]+* Backport the `Generic(1)` instances for `Kleisli` introduced in `base-4.14`.++# 1.13 [2019.08.27]+* Make `GSemigroup` a superclass of `GMonoid`. Similarly, make+  `GSemigroup'` a superclass of `GMonoid'`.+* In the instance `GMonoid (Maybe a)`, relax the constraint on `a` from+  `GMonoid` to `GSemigroup`.++# 1.12.4 [2019.04.26]+* Support `th-abstraction-0.3.0.0` or later.++# 1.12.3 [2019.02.09]+* Support `template-haskell-2.15`.+* Add a `gshowList` method to `GShow`, which lets us avoid the need for+  `OverlappingInstances` in `Generics.Deriving.TH`. As a consequence, the+  `GShow String` instance has been removed, as it is now fully subsumed by+  the `GShow [a]` instance (with which it previously overlapped).+* Functions in `Generics.Deriving.TH` now balance groups of `(:*:)` and `(:+:)`+  as much as possible (`deriving Generic` was already performing this+  optimization, and now `generic-deriving` does too).+* Add a `Generics.Deriving.Default` module demonstrating and explaining+  how and why to use `DerivingVia`. There is also a test suite with+  further examples.++# 1.12.2 [2018.06.28]+* Backport the `Generic(1)` instances for `Data.Ord.Down`, introduced in+  `base-4.12`. Add `GEq`, `GShow`, `GSemigroup`, `GMonoid`, `GFunctor`,+  `GFoldable`, `GTraversable`, and `GCopoint` instances for `Down`.+* Refactor internals using `th-abstraction`.+* Adapt to `Maybe` moving to `GHC.Maybe` in GHC 8.6.++# 1.12.1 [2018.01.11]+* Remove a test that won't work on GHC 8.4.++# 1.12 [2017.12.07]+* Adapt to the `EmptyDataDeriving` proposal (introduced in GHC 8.4):+  * `Generics.Deriving.TH` now derives `to(1)` and `from(1)` implementations+    for empty data types that are strict in the argument.+  * Introduce an `EmptyCaseOptions` field to `Options` in+    `Generics.Deriving.TH`, which controls whether generated `from(1)`/`to(1)`+    implementations for empty data types should use the `EmptyCase` extension+    or not (as is the case in GHC 8.4).+  * Add `mkFrom0Options`, `mkFrom1Options`, `mkTo0Options`, and `mkTo1Options`+    functions to `Generics.Deriving.TH`, which take `EmptyCaseOptions` as+    arguments.+  * The backported instances for `V1` are now maximally lazy, as per+    `EmptyDataDeriving`. (Previously, some instances would unnecessarily force+    their argument, such as the `Eq` and `Ord` instances.)+  * Add instances for `V1` in `Generics.Deriving.Copoint`, `.Eq`, `.Foldable`,+    `.Functor`, `.Show`, and `.Traversable`.+* Remove the bitrotting `simplInstance` function from `Generics.Deriving.TH`.++# 1.11.2 [2017.04.10]+* Add `GEq`, `GShow`, `GEnum`, and `GIx` instances for the new data types+  in `Foreign.C.Types` (`CBool`) and `System.Posix.Types` (`CBlkSize`,+  `CBlkCnt`, `CClockId`, `CFsBlkCnt`, `CFsFilCnt`, `CId`, `CKey`, and `CTimer`)+  introduced in `base-4.10.0.0`++# 1.11.1 [2016.09.10]+* Fix Template Haskell regression involving data families+* Convert examples to test suite+* Backport missing `Data` and `Typeable` instances for `Rec1`, `M1`, `(:*:)`,+  `(:+:)`, and `(:.:)`++# 1.11+* The behavior of functions in `Generics.Deriving.TH` have changed with respect+  to when type synonyms are generated for `Rep(1)` definitions. In particular:++  * By default, `deriveRepresentable(1)` will no longer define its `Rep(1)`+    type family instance in terms of the type synonym that has to be generated+    with `deriveRep(1)`. Similarly, `deriveAll(1)` and `deriveAll0And1` will no+    longer generate a type synonym. Instead, they will generate `Generic(1)`+    instances that directly define the `Rep(1)` instance inline. If you wish+    to revert to the old behavior, you will need to use the variants of those+    functions suffixed with `-Options`.+  * New functions `makeRep0Inline` and `makeRep1Inline` have been added which,+    for most purposes, should replace uses of `makeRep0`/`makeRep0FromType`+    and `makeRep1`/`makeRep1FromType` (but see the next bullet point for a+    caveat).+  * The use of `deriveRep(1)`, `makeRep0`/`makeRep0FromType`, and+    `makeRep1`/`makeRep1FromType` are now discouraged, but those functions are+    still available. The reason is that on GHC 7.0/7.2/7.4, it is impossible to use+    `makeRep0Inline`/`makeRep1Inline` due to a GHC bug. Therefore, you must use+    `makeRep0`/`makeRep1` and `deriveRep(1)` on GHC 7.0/7.2/7.4 out of necessity.++  These changes make dealing with `Generic` instances that involve `PolyKinds`+  and `TypeInType` much easier.+* All functions suffixed in `-WithKindSigs` in `Generics.Deriving.TH` have been+  removed in favor of a more sensible `-Options` suffixing scheme. The ability to+  toggle whether explicit kind signatures are used on type variable binders has+  been folded into `KindSigOptions`, which is an explicit argument to+  `deriveRep0Options`/`deriveRep1Options` and also a field in the more general+  'Options' data type.+* Furthermore, the behavior of derived instances' kind signatures has changed.+  By default, the TH code will now _always_ use explicit kind signatures+  whenever possible, regardless of whether you're working with plain data types+  or data family instances. This makes working with `TypeInType` less+  surprising, but at the cost of making it slightly more awkward to work with+  derived `Generic1` instances that constrain kinds to `*` by means of `(:.:)`.+* Since `Generic1` is polykinded on GHC 8.2 and later, the functions in+  `Generics.Deriving.TH` will no longer unify the kind of the last type+  parameter to be `*`.+* Fix a bug in which `makeRep` (and similarly named functions) would not check+  whether the argument type can actually have a well kinded `Generic(1)`+  instance.+* Backport missing `Foldable` and `Traversable` instances for `Rec1`++# 1.10.7+* Renamed internal modules to avoid using apostrophes (averting this bug:+  https://github.com/haskell/cabal/issues/3631)++# 1.10.6+* A new `base-4-9` Cabal flag was added to more easily facilitate installing+  `generic-deriving` with manually installed versions of `template-haskell`.++# 1.10.5+* Apply an optimization to generated `to(1)`/`from(1)` instances that factors out+  common occurrences of `M1`. See+  http://git.haskell.org/ghc.git/commit/9649fc0ae45e006c2ed54cc5ea2414158949fadb+* Export internal typeclass names+* Fix Haddock issues with GHC 7.8++# 1.10.4.1+* Fix Haddock parsing issue on GHC 8.0++# 1.10.4+* Backported `MonadPlus` and `MonadZip` instances for `U1`, and made the+  `Functor`, `Foldable`, `Traversable`, `Alternative`, and `Monad` instances+  for `U1` lazier to correspond with `base-4.9`++# 1.10.3+* Backported `Enum`, `Bounded`, `Ix`, `Functor`, `Applicative`, `Monad`,+ `MonadFix`, `MonadPlus`, `MonadZip`, `Foldable`, `Traversable`, and+ `Data` instances (introduced in `base-4.9`) for datatypes in the+ `Generics.Deriving.Base` module++# 1.10.2+* Fix TH regression on GHC 7.0++# 1.10.1+* Added `Generics.Deriving.Semigroup`+* Added `GMonoid` instance for `Data.Monoid.Alt`+* Fixed a bug in the `GEnum` instances for unsigned `Integral` types+* Added `Safe`/`Trustworthy` pragmas+* Made instances polykinded where possible++# 1.10.0+* On GHC 8.0 and up, `Generics.Deriving.TH` uses the new type literal-based+  machinery+* Rewrote the Template Haskell code to be robust. Among other things, this fixes+  a bug with deriving Generic1 instances on GHC 7.8, and makes it easier to+  derive Generic1 instances for datatypes that utilize GHC 8.0's `-XTypeInType`+  extension.+* Added `deriveAll0` and `makeRep0` for symmetry with `deriveAll1` and+  `makeRep1`+* Added`makeRep0FromType` and `makeRep1FromType` to make it easier to pass+  in the type instance (instead of having to pass each individual type+  variable, which can be error-prone)+* Added functions with the suffix `-WithKindSigs` to allow generating type+  synonyms with explicit kind signatures in the presence of kind-polymorphic+  type variables. This is necessary for some datatypes that use+  `-XTypeInType` to have derived `Generic(1)` instances, but is not turned on+  by default since the TH kind inference is not perfect and would cause+  otherwise valid code to be rejected. Use only if you know what you are doing.+* Fixed bug where a datatype with a single, nullary constructor would generate+  incorrect `Generic` instances+* More sensible `GEnum` instances for fixed-size integral types+* Added `GCopoint`, `GEnum`, `GEq`, `GFoldable`, `GFunctor`, `GMonoid`,+  `GShow`, and `GTraversable` instances for datatypes introduced in GHC 8.0+* Backported `Generic(1)` instances added in GHC 8.0. Specifically, `Generic`+  instances for `Complex` (`base-4.4` and later) `ExitCode`, and `Version`; and+  `Generic1` instances for `Complex` (`base-4.4` and later) and `Proxy`+  (`base-4.7` and later). Added `GEnum`, `GEq`, `GFoldable`, `GFunctor`, `GIx`,+  `GShow`, and `GTraversable` instances for these datatypes where appropriate.++# 1.9.0+* Allow deriving of Generic1 using Template Haskell+* Allow deriving of Generic(1) for data families+* Allow deriving of Generic(1) for constructor-less plain datatypes (but not+  data families, due to technical restrictions)+* Support for unboxed representation types on GHC 7.11++* More `GCopoint`, `GEnum`, `GEq`, `GFoldable`, `GFunctor`, `GIx`, `GMonoid`,+  `GShow`, and `GTraversable` instances+* The field accessors for the `(:+:)` type in `Generics.Deriving.Base` have+  been removed to be consistent with `GHC.Generics`+* Ensure that TH generates definitions for isNewtype and packageName, if a+  recent-enough version of GHC is used+* Ensure that TH-generated names are unique for a given data type's module and+  package (similar in spirit to Trac #10487)+* Allow building on stage-1 compilers
LICENSE view
@@ -1,28 +1,28 @@-Copyright (c) 2010 Universiteit Utrecht
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-3. Neither the name of Universiteit Utrecht nor the names of its contributors
-   may be used to endorse or promote products derived from this software without
-   specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+Copyright (c) 2010 Universiteit Utrecht+All rights reserved.++Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+   list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+   this list of conditions and the following disclaimer in the documentation+   and/or other materials provided with the distribution.++3. Neither the name of Universiteit Utrecht nor the names of its contributors+   may be used to endorse or promote products derived from this software without+   specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ README.md view
@@ -0,0 +1,86 @@+## `generic-deriving`: Generic programming library for generalised deriving+[![Hackage](https://img.shields.io/hackage/v/generic-deriving.svg)][Hackage: generic-deriving]+[![Hackage Dependencies](https://img.shields.io/hackage-deps/v/generic-deriving.svg)](http://packdeps.haskellers.com/reverse/generic-deriving)+[![Haskell Programming Language](https://img.shields.io/badge/language-Haskell-blue.svg)][Haskell.org]+[![BSD3 License](http://img.shields.io/badge/license-BSD3-brightgreen.svg)][tl;dr Legal: BSD3]+[![Build Status](https://github.com/dreixel/generic-deriving/workflows/Haskell-CI/badge.svg)](https://github.com/dreixel/generic-deriving/actions?query=workflow%3AHaskell-CI)++[Hackage: generic-deriving]:+  http://hackage.haskell.org/package/generic-deriving+  "generic-deriving package on Hackage"+[Haskell.org]:+  http://www.haskell.org+  "The Haskell Programming Language"+[tl;dr Legal: BSD3]:+  https://tldrlegal.com/license/bsd-3-clause-license-%28revised%29+  "BSD 3-Clause License (Revised)"++This package provides functionality for generalising the deriving mechanism+in Haskell to arbitrary classes. It was first described in the paper:++* [A generic deriving mechanism for Haskell](http://dreixel.net/research/pdf/gdmh.pdf).+  Jose Pedro Magalhaes, Atze Dijkstra, Johan Jeuring, and Andres Loeh. Haskell'10.++The current implementation integrates with the new GHC Generics. See+http://www.haskell.org/haskellwiki/GHC.Generics for more information.+Template Haskell code is provided for supporting older GHCs.++This library is organized as follows:++* `Generics.Deriving.Base` defines the core functionality for GHC generics,+  including the `Generic(1)` classes and representation data types.+  On modern versions of GHC, this simply re-exports `GHC.Generics` from+  `base`. On older versions of GHC, this module backports parts of+  `GHC.Generics` that were not included at the time, including `Generic(1)`+  instances.++* `Generics.Deriving.TH` implements Template Haskell functionality for+  deriving instances of `Generic(1)`.++* Educational code: in order to provide examples of how to define and use+  `GHC.Generics`-based defaults, this library offers a number of modules+  which define examples of type classes along with default implementations+  for the classes' methods. Currently, the following modules are provided:++  * `Generics.Deriving.Copoint`++  * `Generics.Deriving.ConNames`++  * `Generics.Deriving.Enum`++  * `Generics.Deriving.Eq`++  * `Generics.Deriving.Foldable`++  * `Generics.Deriving.Functor`++  * `Generics.Deriving.Monoid`++  * `Generics.Deriving.Semigroup`++  * `Generics.Deriving.Show`++  * `Generics.Deriving.Traversable`++  * `Generics.Deriving.Uniplate`++  It is worth emphasizing that these modules are primarly intended for+  educational purposes. Many of the classes in these modules resemble other+  commonly used classes—for example, `GShow` from `Generics.Deriving.Show`+  resembles `Show` from `base`—but in general, the classes that+  `generic-deriving` defines are not drop-in replacements. Moreover, the+  generic defaults that `generic-deriving` provide often make simplifying+  assumptions that may violate expectations of how these classes might work+  elsewhere. For example, the generic default for `GShow` does not behave+  exactly like `deriving Show` would.++  If you are seeking `GHC.Generics`-based defaults for type classes in+  `base`, consider using the+  [`generic-data`](http://hackage.haskell.org/package/generic-data) library.++* `Generics.Deriving.Default` provides newtypes that allow leveraging the+  generic defaults in this library using the `DerivingVia` GHC language+  extension.++* `Generics.Deriving` re-exports `Generics.Deriving.Base`,+  `Generics.Deriving.Default`, and a selection of educational modules.
Setup.hs view
@@ -1,6 +1,6 @@-module Main (main) where
-
-import Distribution.Simple
-
-main :: IO ()
-main = defaultMain
+module Main (main) where++import Distribution.Simple++main :: IO ()+main = defaultMain
− examples/Examples.hs
@@ -1,583 +0,0 @@-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE StandaloneDeriving #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE DatatypeContexts #-}
-{-# LANGUAGE DeriveFunctor #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DeriveGeneric #-}
-#endif
-
-module Main (
-  -- * Run all tests
-  main
-  ) where
-
-import Prelude hiding (Either(..))
-import Generics.Deriving
-import Generics.Deriving.TH
-
-
---------------------------------------------------------------------------------
--- Temporary tests for TH generation
---------------------------------------------------------------------------------
-
-data (:/:) f a = MyType1Nil
-               | MyType1Cons { myType1Rec :: (f :/: a), myType2Rec :: MyType2 }
-               | MyType1Cons2 (f :/: a) Int a (f a) 
-
-#if __GLASGOW_HASKELL__ >= 701
-  deriving Generic
-#endif
-
-data MyType2 = MyType2 Float ([] :/: Int)
-
-#if __GLASGOW_HASKELL__ < 701
-
-$(deriveAll ''(:/:))
-$(deriveAll ''MyType2)
-
-#else
-
--- deriving instance Generic (f :/: a)
-deriving instance Generic MyType2
-
-#endif
-
---------------------------------------------------------------------------------
--- Example: Haskell's lists and Maybe
---------------------------------------------------------------------------------
-
-hList1, hList2 :: [Int]
-hList1 = [1..10]
-hList2 = [2,4..]
-
-maybe1 = Nothing
-maybe2 = Just (Just 'p')
-
-double :: [Int] -> [Int]
-double []     = []
-double (x:xs) = x:x:xs
-
-testsStandard = [ gshow hList1
-                , gshow (children maybe2)
-                , gshow (transform (const "abc") [])
-                , gshow (transform double hList1)
-                , gshow (geq hList1 hList1)
-                , gshow (geq maybe1 maybe2)
-                , gshow (take 5 (genum :: [Maybe Int]))
-                , gshow (take 15 (genum :: [[Int]]))
-                , gshow (range ([0], [1::Int]))
-                , gshow (inRange ([0], [3,5::Int]) hList1) ]
-
---------------------------------------------------------------------------------
--- Example: trees of integers (kind *)
---------------------------------------------------------------------------------
-
-data Tree = Empty | Branch Int Tree Tree
-
-#if __GLASGOW_HASKELL__ >= 701
-
-deriving instance Generic Tree
-
-instance GShow Tree
-instance Uniplate Tree
-instance GEnum Tree
-
-#else
-
-$(deriveAll ''Tree)
-
-instance GShow    Tree where gshowsPrec = gshowsPrecdefault
-instance Uniplate Tree where
-  children   = childrendefault
-  context    = contextdefault
-  descend    = descenddefault
-  descendM   = descendMdefault
-  transform  = transformdefault
-  transformM = transformdefault
-instance GEnum    Tree where genum      = genumDefault
-
-#endif
-
-upgradeTree :: Tree -> Tree
-upgradeTree Empty          = Branch 0 Empty Empty
-upgradeTree (Branch n l r) = Branch (succ n) l r
-
--- Example usage
-tree = Branch 2 Empty (Branch 1 Empty Empty)
-testsTree = [ gshow tree 
-            , gshow (children tree)
-            , gshow (descend (descend (\_ -> Branch 0 Empty Empty)) tree)
-            , gshow (context tree [Branch 1 Empty Empty,Empty])
-            , gshow (transform upgradeTree tree)
-            , gshow (take 10 (genum :: [Tree])) ]
-
---------------------------------------------------------------------------------
--- Example: lists (kind * -> *)
---------------------------------------------------------------------------------
-
-data List a = Nil | Cons a (List a) 
-
-#if __GLASGOW_HASKELL__ >= 701
-deriving instance Generic (List a)
-#else
-
-type Rep0List_ a = D1 List_ ((:+:) (C1 Nil_ U1) (C1 Cons_ ((:*:) (Par0 a) (Rec0 (List a)))))
-instance Generic (List a) where
-  type Rep (List a) = Rep0List_ a
-  from Nil        = M1 (L1 (M1 U1))
-  from (Cons h t) = M1 (R1 (M1 ((:*:) (K1 h) (K1 t))))
-  to (M1 (L1 (M1 U1)))                     = Nil
-  to (M1 (R1 (M1 (K1 h :*: K1 t)))) = Cons h t
-
-#endif
-
-#if __GLASGOW_HASKELL__ >= 705
-deriving instance Generic1 List
-#else
-
-data List_
-data Nil_
-data Cons_
-
-instance Datatype List_ where
-  datatypeName _ = "List"
-  moduleName   _ = "Examples"
-
-instance Constructor Nil_  where conName _ = "Nil"
-instance Constructor Cons_ where conName _ = "Cons"
-
-type Rep1List_ = D1 List_ ((:+:) (C1 Nil_ U1) (C1 Cons_ ((:*:) Par1 (Rec1 List))))
-instance Generic1 List where
-  type Rep1 List = Rep1List_
-  from1 Nil        = M1 (L1 (M1 U1))
-  from1 (Cons h t) = M1 (R1 (M1 (Par1 h :*: Rec1 t)))
-  to1 (M1 (L1 (M1 U1)))                         = Nil
-  to1 (M1 (R1 (M1 (Par1 h :*: Rec1 t)))) = Cons h t
-
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
--- Instance for generic functions (should be automatically generated)
-instance GFunctor List where
-  gmap = gmapdefault
-
-instance (GShow a) => GShow (List a) where
-  gshowsPrec = gshowsPrecdefault
-
-instance (Uniplate a) => Uniplate (List a) where
-  children   = childrendefault
-  context    = contextdefault
-  descend    = descenddefault
-  descendM   = descendMdefault
-  transform  = transformdefault
-  transformM = transformdefault
-
-#else
-
-instance                 GFunctor  List
-instance (GShow a)    => GShow    (List a)
-instance (Uniplate a) => Uniplate (List a)
-
-#endif
-
--- Example usage
-list = Cons 'p' (Cons 'q' Nil)
-listlist = Cons list (Cons Nil Nil) -- ["pq",""]
-
-testsList = [ gshow (gmap fromEnum list)
-            , gshow (gmap gshow listlist)
-            , gshow list
-            , gshow listlist
-            , gshow (children list)
-            , gshow (children listlist) ]
-
-
---------------------------------------------------------------------------------
--- Example: Nested datatype, record selectors
---------------------------------------------------------------------------------
-
-data Nested a = Leaf | Nested { value :: a, rec :: Nested [a] }
-  deriving Functor
-
-#if __GLASGOW_HASKELL__ >= 701
-deriving instance Generic (Nested a)
-#endif
-
-#if __GLASGOW_HASKELL__ < 705
-$(deriveMeta ''Nested)
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
-$(deriveRepresentable0 ''Nested)
-#endif
-
-#if __GLASGOW_HASKELL__ >= 705
-deriving instance Generic1 Nested
-#else
-
-type RepNested = D1 Nested_ (C1 Nested_Leaf_ U1 :+: C1 Nested_Nested_ (Par1 :*: Nested :.: Rec1 []))
-instance Generic1 Nested where
-  type Rep1 Nested = RepNested
-  from1 Leaf = M1 (L1 (M1 U1))
-  from1 (Nested a l) = M1 (R1 (M1 (Par1 a :*: Comp1 (gmap Rec1 l))))
-  to1 (M1 (L1 (M1 U1))) = Leaf
-  to1 (M1 (R1 (M1 (Par1 a :*: Comp1 l)))) = Nested a (gmap unRec1 l)
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
--- Instance for gshow (should be automatically generated)
-instance (GShow a) => GShow (Nested a) where
-  gshowsPrec = gshowsPrecdefault
-
-instance GFunctor Nested where
-  gmap = gmapdefault
-
-#else 
-
-instance (GShow a) => GShow (Nested a)
-instance GFunctor Nested
-
-#endif
-
--- Example usage
-nested :: Nested Int
-nested = Nested 1 (Nested [2] (Nested [[3],[4,5],[]] Leaf))
---nested = Nested 1 (Nested (Nested 1 Leaf) Leaf)
-
-
-testsNested = [ gshow nested
-              , gshow (gmap gshow nested) ]
-
---------------------------------------------------------------------------------
--- Example: Type composition
---------------------------------------------------------------------------------
-
-data Rose a = Rose [a] [Rose a]
-
-#if __GLASGOW_HASKELL__ >= 701
-deriving instance Generic (Rose a)
-#else
-
-type Rep0Rose a = D1 RoseD (C1 RoseC (Rec0 [a] :*: Rec0 [Rose a]))
-instance Generic (Rose a) where
-  type Rep (Rose a) = Rep0Rose a
-  from (Rose a x) = M1 (M1 (K1 a :*: K1 x))
-  to (M1 (M1 (K1 a :*: K1 x))) = Rose a x
-
-#endif
-
-#if __GLASGOW_HASKELL__ >= 705
-deriving instance Generic1 Rose
-#else
-
-data RoseD
-data RoseC
-
-instance Datatype RoseD where
-  datatypeName _ = "Rose"
-  moduleName   _ = "Examples"
-
-instance Constructor RoseC where conName _ = "Rose"
-
--- Generic1 instances
-type RepRose = D1 RoseD (C1 RoseC (Rec1 [] :*: [] :.: Rec1 Rose))
-instance Generic1 Rose where
-  type Rep1 Rose = RepRose
-  from1 (Rose a x) = M1 (M1 (Rec1 a :*: Comp1 (gmap Rec1 x)))
-  to1 (M1 (M1 (Rec1 a :*: Comp1 x))) = Rose a (gmap unRec1 x)
-
-#endif
-
-#if __GLASGOW_HASKELL_ >= 701
-
-instance (GShow a) => GShow (Rose a)
-instance GFunctor Rose
-
-#else
-
--- Instance for gshow (should be automatically generated)
-instance (GShow a) => GShow (Rose a) where
-  gshowsPrec = gshowsPrecdefault
-
-instance GFunctor Rose where
-  gmap = gmapdefault
-
-#endif
-
--- Example usage
-rose1 :: Rose Int
-rose1 = Rose [1,2] [Rose [3,4] [], Rose [5] []]
-
-testsRose = [ gshow rose1
-            , gshow (gmap gshow rose1) ]
-
---------------------------------------------------------------------------------
--- Example: Higher-order kinded datatype, type composition
---------------------------------------------------------------------------------
-
-data GRose f a = GRose (f a) (f (GRose f a))
-
-deriving instance (Functor f) => Functor (GRose f)
-
-#if __GLASGOW_HASKELL__ >= 701
-deriving instance Generic (GRose f a)
-#endif
-
-#if __GLASGOW_HASKELL__ < 705
-$(deriveMeta ''GRose)
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
-$(deriveRepresentable0 ''GRose)
-#endif
-
-#if __GLASGOW_HASKELL__ >= 705
-deriving instance (Functor f) => Generic1 (GRose f)
-#else
-
-type Rep1GRose f = D1 GRose_ (C1 GRose_GRose_ (Rec1 f :*: f :.: (Rec1 (GRose f))))
-instance (GFunctor f) => Generic1 (GRose f) where
-  type Rep1 (GRose f) = Rep1GRose f
-  from1 (GRose a x) = M1 (M1 (Rec1 a :*: Comp1 (gmap Rec1 x)))
-  to1 (M1 (M1 (Rec1 a :*: Comp1 x))) = GRose a (gmap unRec1 x)
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
--- Requires UndecidableInstances
-instance (GShow (f a), GShow (f (GRose f a))) => GShow (GRose f a) where
-  gshowsPrec = gshowsPrecdefault
-
-instance (GFunctor f) => GFunctor (GRose f) where
-  gmap = gmapdefault
-
-#else
-
-instance (GShow (f a), GShow (f (GRose f a))) => GShow (GRose f a)
-instance (Functor f, GFunctor f) => GFunctor (GRose f)
-
-#endif
-
--- Example usage
-grose1 :: GRose [] Int
-grose1 = GRose [1,2] [GRose [3] [], GRose [] []]
-
-testsGRose = [ gshow grose1
-             , gshow (gmap gshow grose1) ]
-
---------------------------------------------------------------------------------
--- Example: NGRose (minimal)
---------------------------------------------------------------------------------
-
--- Cannot represent because of nesting on an argument other than the parameter
-{-
-data NGRose f a = NGNode a (f (NGRose (Comp f f) a))
-data Comp f g a = Comp (f (g a))
-
-type Rep0NGRose f a = Par0 a :*: Rec0 (f (NGRose (Comp f f) a))
-instance Generic (NGRose f a) (Rep0NGRose f a) where
-  from (NGNode a x) = K1 a :*: K1 x
-  to (K1 a :*: K1 x) = NGNode a x
-
-type Rep0Comp f g a = Rec0 (f (g a))
-instance Generic (Comp f g a) (Rep0Comp f g a) where
-  from (Comp x) = K1 x
-  to (K1 x) = Comp x
-
-type Rep1Comp f g = f :.: Rec1 g
-instance (GFunctor f) => Generic1 (Comp f g) (Rep1Comp f g) where
-  from1 (Comp x) = Comp1 (gmap Rec1 x)
-  to1 (Comp1 x) = Comp (gmap unRec1 x)
-
-type Rep1NGRose f = Par1 :*: f :.: Rec1 (NGRose (Comp f f))
-instance (GFunctor f) => Generic1 (NGRose f) (Rep1NGRose f) where
-  from1 (NGNode a x) = Par1 a :*: (Comp1 (gmap Rec1 x))
-  to1 (Par1 a :*: Comp1 x) = NGNode a (gmap unRec1 x)
-
-instance (GShow a, GShow (f (NGRose (Comp f f) a))) => GShow (NGRose f a) where
-  gshowsPrec = t undefined where
-    t :: (GShow a, GShow (f (NGRose (Comp f f) a))) => Rep0NGRose f a x -> NGRose f a -> ShowS
-    t = gshowsPrecdefault
-
-instance (GShow a) => GShow (Comp f g a) where
-  gshowsPrec = t undefined where
-    t :: (GShow a) => Rep0Comp f g a x -> Comp f g a -> ShowS
-    t = gshowsPrecdefault
-
-instance (GFunctor f, GFunctor (Comp f f)) => GFunctor (NGRose f) where
-  gmap = t undefined where
-    t :: (GFunctor f, GFunctor (Comp f f)) => Rep1NGRose f a -> (a -> b) -> NGRose f a -> NGRose f b
-    t = gmapdefault
-
-ngrose1 :: NGRose [] Int
-ngrose1 = NGNode 0 [ngrose2, ngrose2]
-
-ngrose2 :: NGRose (Comp [] []) Int
-ngrose2 = NGNode 1 (Comp [])
-
-testsNGRose = [ gshow ngrose1
-              , gshow (gmap gshow ngrose1) ]
--}
-
---------------------------------------------------------------------------------
--- Example: Double type composition (minimal)
---------------------------------------------------------------------------------
-
--- Add this to EHC
-unComp (Comp1 x) = x
-
-data Weird a = Weird [[[a]]] deriving Show
-
-type Rep1Weird = [] :.: [] :.: Rec1 []
-instance Generic1 Weird where
-  type Rep1 Weird = Rep1Weird
-  from1 (Weird x) = Comp1 (gmap (Comp1 . gmap Rec1) x)
-  to1 (Comp1 x) = Weird (gmap (gmap unRec1 . unComp) x)
-
-#if __GLASGOW_HASKELL__ >= 701
-
-instance GFunctor Weird
-
-#else 
-
-instance GFunctor Weird where
-  gmap = gmapdefault
-
-#endif
-
---------------------------------------------------------------------------------
--- Example: Nested datatype Bush (minimal)
---------------------------------------------------------------------------------
-
-data Bush a = BushNil | BushCons a (Bush (Bush a)) deriving Functor
-
-#if __GLASGOW_HASKELL__ >= 701
-deriving instance Generic (Bush a)
-#endif
-
-#if __GLASGOW_HASKELL__ < 705
-$(deriveMeta ''Bush)
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
-$(deriveRepresentable0 ''Bush)
-#endif
-
-#if __GLASGOW_HASKELL__ >= 705
-deriving instance Generic1 Bush
-#else
-
-type Rep1Bush = U1 :+: Par1 :*: Bush :.: Rec1 Bush
-instance Generic1 Bush where
-  type Rep1 Bush = Rep1Bush
-  from1 BushNil = L1 U1
-  from1 (BushCons a b) = R1 (Par1 a :*: Comp1 (gmap Rec1 b))
-  to1 (L1 U1) = BushNil
-  to1 (R1 (Par1 a :*: Comp1 b)) = BushCons a (gmap unRec1 b)
-
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
-
-instance GFunctor Bush where
-  gmap = gmapdefault
-
-instance (GShow a) => GShow (Bush a) where
-  gshowsPrec = gshowsPrecdefault
-
-#else
-
-instance GFunctor Bush
-instance (GShow a) => GShow (Bush a)
-
-#endif
-
--- Example usage
-bush1 :: Bush Int
-bush1 = BushCons 0 (BushCons (BushCons 1 BushNil) BushNil)
-
-testsBush = [ gshow bush1
-            , gshow (gmap gshow bush1) ]
-
---------------------------------------------------------------------------------
--- Example: Two parameters, datatype constraint, nested on other parameter
---------------------------------------------------------------------------------
-
--- Any constraints on |b| mean we cannot generate the Generic1 instance
--- Constraints on |a| are just propagated to Generic and generic
--- function instances
-data (Show a) => Either a b = Left (Either [a] b) | Right b
-
-
--- Generic1 instances
-type Rep0Either a b = Rec0 (Either [a] b) :+: Rec0 b
-instance (Show a) => Generic (Either a b) where
-  type Rep (Either a b) = Rep0Either a b
-  from (Left a)  = L1 (K1 a)
-  from (Right a) = R1 (K1 a)
-  to (L1 (K1 a)) = Left a
-  to (R1 (K1 a)) = Right a
-
-type RepEither a = Rec1 (Either [a]) :+: Par1
-instance (Show a) => Generic1 (Either a) where
-  type Rep1 (Either a) = RepEither a
-  from1 (Left a)  = L1 (Rec1 a)
-  from1 (Right a) = R1 (Par1 a)
-  to1 (L1 (Rec1 a)) = Left a
-  to1 (R1 (Par1 a)) = Right a
-
-
-#if __GLASGOW_HASKELL__ < 701
--- Instance for gshow (should be automatically generated)
-instance (Show a, GShow a, GShow b) => GShow (Either a b) where
-  gshowsPrec = gshowsPrecdefault
-
-instance (Show a) => GFunctor (Either a) where
-  gmap = gmapdefault
-
-#else
-
-instance (Show a, GShow a, GShow b) => GShow (Either a b)
-instance (Show a) => GFunctor (Either a)
-
-#endif
-
-either1 :: Either Int Char
-either1 = Left either2
-
-either2 :: Either [Int] Char
-either2 = Right 'p'
-
-testsEither = [ gshow either1
-              , gshow (gmap gshow either1) ]
-
---------------------------------------------------------------------------------
--- Main tests
---------------------------------------------------------------------------------
-
-main :: IO ()
-main = do
-        let p = putStrLn . ((++) "- ") . show
-        putStrLn "[] and Maybe tests:"
-        mapM_ p testsStandard
-        putStrLn "Tests for Tree:"
-        mapM_ p testsTree
-        putStrLn "\nTests for List:"
-        mapM_ p testsList
-        putStrLn "\nTests for Rose:"
-        mapM_ p testsRose
-        putStrLn "\nTests for GRose:"
-        mapM_ p testsGRose
-        putStrLn "\nTests for Either:"
-        mapM_ p testsEither
-        putStrLn "\nTests for Nested:"
-        mapM_ p testsNested
-        putStrLn "\nTests for Bush:"
-        mapM_ p testsBush
generic-deriving.cabal view
@@ -1,56 +1,150 @@-name:                   generic-deriving
-version:                1.5.0
-synopsis:               Generic programming library for generalised deriving.
-description:
-
-  This package provides functionality for generalising the deriving mechanism
-  in Haskell to arbitrary classes. It was first described in the paper:
-  .
-  *  /A generic deriving mechanism for Haskell/.
-     Jose Pedro Magalhaes, Atze Dijkstra, Johan Jeuring, and Andres Loeh.
-     Haskell'10.
-  .
-  The current implementation integrates with the new GHC Generics. See
-  <http://www.haskell.org/haskellwiki/GHC.Generics> for more information.
-  Template Haskell code is provided for supporting GHC before version 7.2.
-
-category:               Generics
-copyright:              2011-2013 Universiteit Utrecht, University of Oxford
-license:                BSD3
-license-file:           LICENSE
-author:                 José Pedro Magalhães
-maintainer:             generics@haskell.org
-stability:              experimental
-build-type:             Simple
-cabal-version:          >= 1.6
-tested-with:            GHC == 7.0.3, GHC == 7.2.1, GHC == 7.4.1, GHC == 7.6.1
-extra-source-files:     examples/Examples.hs
-
-source-repository head
-  type: git
-  location: https://github.com/dreixel/generic-deriving
-
-library
-  hs-source-dirs:       src
-  exposed-modules:      Generics.Deriving
-                        Generics.Deriving.Base
-                        Generics.Deriving.Instances
-
-                        Generics.Deriving.ConNames
-                        Generics.Deriving.Enum
-                        Generics.Deriving.Eq
-                        Generics.Deriving.Foldable
-                        Generics.Deriving.Functor
-                        Generics.Deriving.Monoid
-                        Generics.Deriving.Show
-                        Generics.Deriving.Traversable
-                        Generics.Deriving.Uniplate
-
-                        Generics.Deriving.TH
-                        
-  build-depends:        base < 5, template-haskell >=2.4 && <2.10
-  if impl(ghc > 7.0)
-    build-depends:      ghc-prim < 1
-
-  extensions:           CPP
-  ghc-options:          -Wall
+name:                   generic-deriving+version:                1.14.7+synopsis:               Generic programming library for generalised deriving.+description:++  This package provides functionality for generalising the deriving mechanism+  in Haskell to arbitrary classes. It was first described in the paper:+  .+  *  /A generic deriving mechanism for Haskell/.+     Jose Pedro Magalhaes, Atze Dijkstra, Johan Jeuring, and Andres Loeh.+     Haskell'10.+  .+  The current implementation integrates with the new GHC Generics. See+  <http://www.haskell.org/haskellwiki/GHC.Generics> for more information.+  Template Haskell code is provided for supporting older GHCs.+  .+  This library is organized as follows:+  .+  * "Generics.Deriving.Base" defines the core functionality for GHC generics,+    including the @Generic(1)@ classes and representation data types.+    On modern versions of GHC, this simply re-exports "GHC.Generics" from+    @base@. On older versions of GHC, this module backports parts of+    "GHC.Generics" that were not included at the time, including @Generic(1)@+    instances.+  .+  * "Generics.Deriving.TH" implements Template Haskell functionality for+    deriving instances of @Generic(1)@.+  .+  * Educational code: in order to provide examples of how to define and use+    "GHC.Generics"-based defaults, this library offers a number of modules+    which define examples of type classes along with default implementations+    for the classes' methods. Currently, the following modules are provided:+    "Generics.Deriving.Copoint", "Generics.Deriving.ConNames",+    "Generics.Deriving.Enum", "Generics.Deriving.Eq",+    "Generics.Deriving.Foldable", "Generics.Deriving.Functor",+    "Generics.Deriving.Monoid", "Generics.Deriving.Semigroup",+    "Generics.Deriving.Show", "Generics.Deriving.Traversable",+    and "Generics.Deriving.Uniplate".+    .+    It is worth emphasizing that these modules are primarly intended for+    educational purposes. Many of the classes in these modules resemble other+    commonly used classes—for example, @GShow@ from "Generics.Deriving.Show"+    resembles @Show@ from @base@—but in general, the classes that+    @generic-deriving@ defines are not drop-in replacements. Moreover, the+    generic defaults that @generic-deriving@ provide often make simplifying+    assumptions that may violate expectations of how these classes might work+    elsewhere. For example, the generic default for @GShow@ does not behave+    exactly like @deriving Show@ would.+    .+    If you are seeking "GHC.Generics"-based defaults for type classes in+    @base@, consider using the+    @<http://hackage.haskell.org/package/generic-data generic-data>@ library.+  .+  * "Generics.Deriving.Default" provides newtypes that allow leveraging the+    generic defaults in this library using the @DerivingVia@ GHC language+    extension.+  .+  * "Generics.Deriving" re-exports "Generics.Deriving.Base",+    "Generics.Deriving.Default", and a selection of educational modules.++homepage:               https://github.com/dreixel/generic-deriving+bug-reports:            https://github.com/dreixel/generic-deriving/issues+category:               Generics+copyright:              2011-2013 Universiteit Utrecht, University of Oxford+license:                BSD3+license-file:           LICENSE+author:                 José Pedro Magalhães+maintainer:             generics@haskell.org+stability:              experimental+build-type:             Simple+cabal-version:          >= 1.10+tested-with:+                        GHC == 8.0.2+                      , GHC == 8.2.2+                      , GHC == 8.4.4+                      , GHC == 8.6.5+                      , GHC == 8.8.4+                      , GHC == 8.10.7+                      , GHC == 9.0.2+                      , GHC == 9.2.8+                      , GHC == 9.4.8+                      , GHC == 9.6.6+                      , GHC == 9.8.4+                      , GHC == 9.10.3+                      , GHC == 9.12.2+                      , GHC == 9.14.1++extra-source-files:     CHANGELOG.md+                      , README.md++source-repository head+  type: git+  location: https://github.com/dreixel/generic-deriving++library+  hs-source-dirs:       src+  exposed-modules:      Generics.Deriving+                        Generics.Deriving.Base+                        Generics.Deriving.Instances+                        Generics.Deriving.Copoint+                        Generics.Deriving.ConNames+                        Generics.Deriving.Default+                        Generics.Deriving.Enum+                        Generics.Deriving.Eq+                        Generics.Deriving.Foldable+                        Generics.Deriving.Functor+                        Generics.Deriving.Monoid+                        Generics.Deriving.Semigroup+                        Generics.Deriving.Show+                        Generics.Deriving.Traversable+                        Generics.Deriving.Uniplate++                        Generics.Deriving.TH++  other-modules:        Generics.Deriving.Monoid.Internal+                        Generics.Deriving.Semigroup.Internal+                        Generics.Deriving.TH.Internal+                        Generics.Deriving.TH.Post4_9+                        Paths_generic_deriving++  build-depends:        base             >= 4.9   && < 5+                      , containers       >= 0.1   && < 0.9+                      , template-haskell >= 2.11  && < 2.25+                        -- TODO: Eventually, we should bump the lower version+                        -- bounds to >=0.6 so that we can remove some CPP in+                        -- Generics.Deriving.TH.Internal.+                      , th-abstraction   >= 0.4   && < 0.8++  default-language:     Haskell2010+  ghc-options:          -Wall++test-suite spec+  type:                 exitcode-stdio-1.0+  main-is:              Spec.hs+  other-modules:        DefaultSpec+                        EmptyCaseSpec+                        ExampleSpec+                        T68Spec+                        T80Spec+                        T82Spec+                        TypeInTypeSpec+  build-depends:        base+                      , generic-deriving+                      , hspec            >= 2    && < 3+  build-tool-depends:   hspec-discover:hspec-discover+  hs-source-dirs:       tests+  default-language:     Haskell2010+  ghc-options:          -Wall -threaded -rtsopts+  if impl(ghc >= 8.6)+    ghc-options:        -Wno-star-is-type
src/Generics/Deriving.hs view
@@ -1,20 +1,24 @@-
-module Generics.Deriving (
-
-    module Generics.Deriving.Base,
-    module Generics.Deriving.ConNames,
-    module Generics.Deriving.Enum,
-    module Generics.Deriving.Eq,
-    module Generics.Deriving.Functor,
-    module Generics.Deriving.Show,
-    module Generics.Deriving.Uniplate
-    
-  ) where
-
-import Generics.Deriving.Base
-import Generics.Deriving.ConNames
-import Generics.Deriving.Enum
-import Generics.Deriving.Eq
-import Generics.Deriving.Functor
-import Generics.Deriving.Show
-import Generics.Deriving.Uniplate
++module Generics.Deriving (++    module Generics.Deriving.Base,+    module Generics.Deriving.Copoint,+    module Generics.Deriving.ConNames,+    module Generics.Deriving.Default,+    module Generics.Deriving.Enum,+    module Generics.Deriving.Eq,+    module Generics.Deriving.Functor,+    module Generics.Deriving.Show,+    module Generics.Deriving.Uniplate++  ) where++import Generics.Deriving.Base+import Generics.Deriving.Copoint+import Generics.Deriving.ConNames+import Generics.Deriving.Default+import Generics.Deriving.Enum+import Generics.Deriving.Eq+import Generics.Deriving.Functor+import Generics.Deriving.Show+import Generics.Deriving.Uniplate
src/Generics/Deriving/Base.hs view
@@ -1,165 +1,7 @@-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE CPP #-}
-
-module Generics.Deriving.Base (
-#if __GLASGOW_HASKELL__ < 701
-  -- * Generic representation types
-    V1, U1(..), Par1(..), Rec1(..), K1(..), M1(..)
-  , (:+:)(..), (:*:)(..), (:.:)(..)
-
-  -- ** Synonyms for convenience
-  , Rec0, Par0, R, P
-  , D1, C1, S1, D, C, S
-
-  -- * Meta-information
-  , Datatype(..), Constructor(..), Selector(..), NoSelector
-  , Fixity(..), Associativity(..), Arity(..), prec
-
-  -- * Generic type classes
-  , Generic(..), Generic1(..)
-
-  ,
-#else
-  module GHC.Generics,
-#endif
-
-  ) where
-
-
-#if __GLASGOW_HASKELL__ >= 701
-import GHC.Generics
-
-#else
---------------------------------------------------------------------------------
--- Representation types
---------------------------------------------------------------------------------
-
--- | Void: used for datatypes without constructors
-data V1 p
-
--- | Unit: used for constructors without arguments
-data U1 p = U1
-
--- | Used for marking occurrences of the parameter
-newtype Par1 p = Par1 { unPar1 :: p }
-
-
--- | Recursive calls of kind * -> *
-newtype Rec1 f p = Rec1 { unRec1 :: f p }
-
--- | Constants, additional parameters and recursion of kind *
-newtype K1 i c p = K1 { unK1 :: c }
-
--- | Meta-information (constructor names, etc.)
-newtype M1 i c f p = M1 { unM1 :: f p }
-
--- | Sums: encode choice between constructors
-infixr 5 :+:
-data (:+:) f g p = L1 { unL1 :: f p } | R1 { unR1 :: g p }
-
--- | Products: encode multiple arguments to constructors
-infixr 6 :*:
-data (:*:) f g p = f p :*: g p
-
--- | Composition of functors
-infixr 7 :.:
-newtype (:.:) f g p = Comp1 { unComp1 :: f (g p) }
-
--- | Tag for K1: recursion (of kind *)
-data R
--- | Tag for K1: parameters (other than the last)
-data P
-
--- | Type synonym for encoding recursion (of kind *)
-type Rec0  = K1 R
--- | Type synonym for encoding parameters (other than the last)
-type Par0  = K1 P
-
--- | Tag for M1: datatype
-data D
--- | Tag for M1: constructor
-data C
--- | Tag for M1: record selector
-data S
-
--- | Type synonym for encoding meta-information for datatypes
-type D1 = M1 D
-
--- | Type synonym for encoding meta-information for constructors
-type C1 = M1 C
-
--- | Type synonym for encoding meta-information for record selectors
-type S1 = M1 S
-
--- | Class for datatypes that represent datatypes
-class Datatype d where
-  -- | The name of the datatype, fully qualified
-  datatypeName :: t d (f :: * -> *) a -> String
-  moduleName   :: t d (f :: * -> *) a -> String
-
--- | Class for datatypes that represent records
-class Selector s where
-  -- | The name of the selector
-  selName :: t s (f :: * -> *) a -> String
-
--- | Used for constructor fields without a name
-data NoSelector
-
-instance Selector NoSelector where selName _ = ""
-
--- | Class for datatypes that represent data constructors
-class Constructor c where
-  -- | The name of the constructor
-  conName :: t c (f :: * -> *) a -> String
-
-  -- | The fixity of the constructor
-  conFixity :: t c (f :: * -> *) a -> Fixity
-  conFixity = const Prefix
-
-  -- | Marks if this constructor is a record
-  conIsRecord :: t c (f :: * -> *) a -> Bool
-  conIsRecord = const False
-
-
--- | Datatype to represent the arity of a tuple.
-data Arity = NoArity | Arity Int
-  deriving (Eq, Show, Ord, Read)
-
--- | Datatype to represent the fixity of a constructor. An infix
--- | declaration directly corresponds to an application of 'Infix'.
-data Fixity = Prefix | Infix Associativity Int
-  deriving (Eq, Show, Ord, Read)
-
--- | Get the precedence of a fixity value.
-prec :: Fixity -> Int
-prec Prefix      = 10
-prec (Infix _ n) = n
-
--- | Datatype to represent the associativy of a constructor
-data Associativity =  LeftAssociative 
-                   |  RightAssociative
-                   |  NotAssociative
-  deriving (Eq, Show, Ord, Read)
-
--- | Representable types of kind *
-class Generic a where
-  type Rep a :: * -> *
-  -- | Convert from the datatype to its representation
-  from  :: a -> Rep a x
-  -- | Convert from the representation to the datatype
-  to    :: Rep a x -> a
-
--- | Representable types of kind * -> *
-class Generic1 f where
-  type Rep1 f :: * -> *
-  -- | Convert from the datatype to its representation
-  from1  :: f a -> Rep1 f a
-  -- | Convert from the representation to the datatype
-  to1    :: Rep1 f a -> f a
-
-#endif
+{-# LANGUAGE Safe #-}++module Generics.Deriving.Base (module GHC.Generics) where++import GHC.Generics++import Generics.Deriving.Instances ()
src/Generics/Deriving/ConNames.hs view
@@ -1,50 +1,63 @@-{-# LANGUAGE TypeOperators         #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE ScopedTypeVariables   #-}
-{-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE TypeSynonymInstances  #-}
-
------------------------------------------------------------------------------
--- |
--- Module      :  Generics.Deriving.ConNames
--- Copyright   :  (c) 2012 University of Oxford
--- License     :  BSD3
---
--- Maintainer  :  generics@haskell.org
--- Stability   :  experimental
--- Portability :  non-portable
---
--- Summary: Return the name of all the constructors of a type.
---
------------------------------------------------------------------------------
-
-module Generics.Deriving.ConNames (
-
-    -- * Functionality for retrieving the names of all the possible contructors
-    --   of a type
-    ConNames(..), conNames
-
-  ) where
-
-import Generics.Deriving.Base
-
-
-class ConNames f where 
-    gconNames :: f a -> [String]
-
-instance (ConNames f, ConNames g) => ConNames (f :+: g) where
-    gconNames (_ :: (f :+: g) a) = gconNames (undefined :: f a) ++
-                                   gconNames (undefined :: g a)
-
-instance (ConNames f) => ConNames (D1 c f) where
-    gconNames (_ :: (D1 c f) a) = gconNames (undefined :: f a)
-    
-instance (Constructor c) => ConNames (C1 c f) where
-    gconNames x = [conName x]
-
--- We should never need any other instances.
-
-
--- | Return the name of all the constructors of the type of the given term.
-conNames :: (Generic a, ConNames (Rep a)) => a -> [String]
-conNames x = gconNames (undefined `asTypeOf` (from x))
+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++{- |+Module      :  Generics.Deriving.ConNames+Copyright   :  (c) 2012 University of Oxford+License     :  BSD3++Maintainer  :  generics@haskell.org+Stability   :  experimental+Portability :  non-portable++Summary: Return the name of all the constructors of a type.+-}++module Generics.Deriving.ConNames (++    -- * Functionality for retrieving the names of the possible contructors+    --   of a type or the constructor name of a given value+    ConNames(..), conNames, conNameOf++  ) where++import Generics.Deriving.Base+++class ConNames f where+    gconNames  :: f a -> [String]+    gconNameOf :: f a -> String++instance (ConNames f, ConNames g) => ConNames (f :+: g) where+    gconNames (_ :: (f :+: g) a) = gconNames (undefined :: f a) +++                                   gconNames (undefined :: g a)++    gconNameOf (L1 x) = gconNameOf x+    gconNameOf (R1 x) = gconNameOf x++instance (ConNames f) => ConNames (D1 c f) where+    gconNames (_ :: (D1 c f) a) = gconNames (undefined :: f a)++    gconNameOf (M1 x) = gconNameOf x++instance (Constructor c) => ConNames (C1 c f) where+    gconNames x = [conName x]++    gconNameOf x = conName x+++-- We should never need any other instances.+++-- | Return the name of all the constructors of the type of the given term.+conNames :: (Generic a, ConNames (Rep a)) => a -> [String]+conNames x = gconNames (undefined `asTypeOf` (from x))++-- | Return the name of the constructor of the given term+conNameOf :: (ConNames (Rep a), Generic a) => a -> String+conNameOf x = gconNameOf (from x)
+ src/Generics/Deriving/Copoint.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeOperators #-}++module Generics.Deriving.Copoint (+  -- * GCopoint class+    GCopoint(..)++  -- * Default method+  , gcopointdefault++  -- * Internal class+  , GCopoint'(..)++  ) where++import           Control.Applicative (WrappedMonad)++import           Data.Functor.Identity (Identity)+import qualified Data.Functor.Sum as Functor (Sum)+import           Data.Monoid (Alt, Dual)+import qualified Data.Monoid as Monoid (Sum)+import           Data.Ord (Down)+import           Data.Semigroup (Arg, First, Last, Max, Min, WrappedMonoid)++import           Generics.Deriving.Base++--------------------------------------------------------------------------------+-- Generic copoint+--------------------------------------------------------------------------------++-- General copoint may return 'Nothing'++class GCopoint' t where+    gcopoint' :: t a -> Maybe a++instance GCopoint' V1 where+    gcopoint' _ = Nothing++instance GCopoint' U1 where+    gcopoint' U1 = Nothing++instance GCopoint' Par1 where+    gcopoint' (Par1 a) = Just a++instance GCopoint' (K1 i c) where+    gcopoint' _ = Nothing++instance GCopoint' f => GCopoint' (M1 i c f) where+    gcopoint' (M1 a) = gcopoint' a++instance (GCopoint' f, GCopoint' g) => GCopoint' (f :+: g) where+    gcopoint' (L1 a) = gcopoint' a+    gcopoint' (R1 a) = gcopoint' a++-- Favours left "hole" for copoint+instance (GCopoint' f, GCopoint' g) => GCopoint' (f :*: g) where+    gcopoint' (a :*: b) = case (gcopoint' a) of+                            Just x -> Just x+                            Nothing -> gcopoint' b++instance (GCopoint f) => GCopoint' (Rec1 f) where+    gcopoint' (Rec1 a) = Just $ gcopoint a++instance (GCopoint f, GCopoint' g) => GCopoint' (f :.: g) where+    gcopoint' (Comp1 x) = gcopoint' . gcopoint $ x++class GCopoint d where+  gcopoint :: d a -> a+  default gcopoint :: (Generic1 d, GCopoint' (Rep1 d))+                   => (d a -> a)+  gcopoint = gcopointdefault++gcopointdefault :: (Generic1 d, GCopoint' (Rep1 d))+                => d a -> a+gcopointdefault x = case (gcopoint' . from1 $ x) of+                      Just x' -> x'+                      Nothing -> error "Data type is not copointed"++-- instance (Generic1 d, GCopoint' (Rep1 d)) => GCopoint d++-- Base types instances+instance GCopoint ((,) a) where+  gcopoint = gcopointdefault++instance GCopoint ((,,) a b) where+  gcopoint = gcopointdefault++instance GCopoint ((,,,) a b c) where+  gcopoint = gcopointdefault++instance GCopoint ((,,,,) a b c d) where+  gcopoint = gcopointdefault++instance GCopoint ((,,,,,) a b c d e) where+  gcopoint = gcopointdefault++instance GCopoint ((,,,,,,) a b c d e f) where+  gcopoint = gcopointdefault++instance GCopoint f => GCopoint (Alt f) where+  gcopoint = gcopointdefault++instance GCopoint (Arg a) where+  gcopoint = gcopointdefault++instance GCopoint Down where+  gcopoint = gcopointdefault++instance GCopoint Dual where+  gcopoint = gcopointdefault++instance GCopoint First where+  gcopoint = gcopointdefault++instance GCopoint Identity where+  gcopoint = gcopointdefault++instance GCopoint Last where+  gcopoint = gcopointdefault++instance GCopoint Max where+  gcopoint = gcopointdefault++instance GCopoint Min where+  gcopoint = gcopointdefault++instance (GCopoint f, GCopoint g) => GCopoint (Functor.Sum f g) where+  gcopoint = gcopointdefault++instance GCopoint Monoid.Sum where+  gcopoint = gcopointdefault++instance GCopoint m => GCopoint (WrappedMonad m) where+  gcopoint = gcopointdefault++instance GCopoint WrappedMonoid where+  gcopoint = gcopointdefault
+ src/Generics/Deriving/Default.hs view
@@ -0,0 +1,271 @@+-- |+-- Module      : Generics.Deriving.Default+-- Description : Default implementations of generic classes+-- License     : BSD-3-Clause+--+-- Maintainer  : generics@haskell.org+-- Stability   : experimental+-- Portability : non-portable+--+-- GHC 8.6 introduced the+-- @<https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html?highlight=derivingvia#extension-DerivingVia DerivingVia>@+-- language extension, which means a typeclass instance can be derived from+-- an existing instance for an isomorphic type. Any newtype is isomorphic+-- to the underlying type. By implementing a typeclass once for the newtype,+-- it is possible to derive any typeclass for any type with a 'Generic' instance.+--+-- For a number of classes, there are sensible default instantiations. In+-- older GHCs, these can be supplied in the class definition, using the+-- @<https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html?highlight=defaultsignatures#extension-DefaultSignatures DefaultSignatures>@+-- extension. However, only one default can be provided! With+-- @<https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html?highlight=derivingvia#extension-DerivingVia DerivingVia>@+-- it is now possible to choose from many+-- default instantiations.+--+-- This package contains a number of such classes. This module demonstrates+-- how one might create a family of newtypes ('Default', 'Default1') for+-- which such instances are defined.+--+-- One might then use+-- @<https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html?highlight=derivingvia#extension-DerivingVia DerivingVia>@+-- as follows. The implementations of the data types are elided here (they+-- are irrelevant). For most cases, either the deriving clause with the+-- data type definition or the standalone clause will work (for some types+-- it is necessary to supply the context explicitly using the latter form).+-- See the source of this module for the implementations of instances for+-- the 'Default' family of newtypes and the source of the test suite for+-- some types which derive instances via these wrappers.++{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE UndecidableInstances #-}++module Generics.Deriving.Default+  ( -- * Kind @*@ (aka @Type@)++    -- $default++    Default(..)++  , -- * Kind @* -> *@ (aka @Type -> Type@)++    -- $default1++    Default1(..)++    -- * Other kinds++    -- $other-kinds+  ) where++import Control.Monad (liftM)++import Generics.Deriving.Base+import Generics.Deriving.Copoint+import Generics.Deriving.Enum+import Generics.Deriving.Eq+import Generics.Deriving.Foldable+import Generics.Deriving.Functor+import Generics.Deriving.Monoid+import Generics.Deriving.Semigroup+import Generics.Deriving.Show+import Generics.Deriving.Traversable+import Generics.Deriving.Uniplate++-- $default+--+-- For classes which take an argument of kind 'Data.Kind.Type', use+-- 'Default'. An example of this class from @base@ would be 'Eq', or+-- 'Generic'.+--+-- These examples use 'GShow' and 'GEq'; they are interchangeable.+--+-- @+-- data MyType = …+--  deriving ('Generic')+--  deriving ('GEq') via ('Default' MyType)+--+-- deriving via ('Default' MyType) instance 'GShow' MyType+-- @+--+-- Instances may be parameterized by type variables.+--+-- @+-- data MyType1 a = …+--  deriving ('Generic')+--  deriving ('GShow') via ('Default' (MyType1 a))+--+-- deriving via 'Default' (MyType1 a) instance 'GEq' a => 'GEq' (MyType1 a)+-- @+--+-- These types both require instances for 'Generic'. This is because the+-- implementations of 'geq' and 'gshowsPrec' for @'Default' b@ have a @'Generic'+-- b@ constraint, i.e. the type corresponding to @b@ require a 'Generic'+-- instance. For these two types, that means instances for @'Generic' MyType@+-- and @'Generic' (MyType1 a)@ respectively.+--+-- It also means the 'Generic' instance is not needed when there is already+-- a generic instance for the type used to derive the relevant instances.+-- For an example, see the documentation of the 'GShow' instance for+-- 'Default', below.++-- | This newtype wrapper can be used to derive default instances for+-- classes taking an argument of kind 'Data.Kind.Type'.+newtype Default a = Default { unDefault :: a }++-- $default1+--+-- For classes which take an argument of kind @'Data.Kind.Type' ->+-- 'Data.Kind.Type'@, use 'Default1'.  An example of this class from @base@+-- would be 'Data.Functor.Classes.Eq1', or 'Generic1'.+--+-- Unlike for @MyType1@, there can be no implementation of these classes for @MyType :: 'Data.Kind.Type'@.+--+-- @+-- data MyType1 a = …+--  deriving ('Generic1')+--  deriving ('GFunctor') via ('Default1' MyType1)+--+-- deriving via ('Default1' MyType1) instance 'GFoldable' MyType1+-- @+--+-- Note that these instances require a @'Generic1' MyType1@ constraint as+-- 'gmap' and 'gfoldMap' have @'Generic1' a@ constraints on the+-- implementations for @'Default1' a@.++-- | This newtype wrapper can be used to derive default instances for+-- classes taking an argument of kind @'Data.Kind.Type' -> 'Data.Kind.Type'@.+newtype Default1 f a = Default1 { unDefault1 :: f a }++-- $other-kinds+--+-- These principles extend to classes taking arguments of other kinds.++--------------------------------------------------------------------------------+-- Eq+--------------------------------------------------------------------------------++instance (Generic a, GEq' (Rep a)) => GEq (Default a) where+  -- geq :: Default a -> Default a -> Bool+  Default x `geq` Default y = x `geqdefault` y++--------------------------------------------------------------------------------+-- Enum+--------------------------------------------------------------------------------++-- | The 'Enum' class in @base@ is slightly different; it comprises 'toEnum' and+-- 'fromEnum'. "Generics.Deriving.Enum" provides functions 'toEnumDefault'+-- and 'fromEnumDefault'.+instance (Generic a, GEq a, Enum' (Rep a)) => GEnum (Default a) where+  -- genum :: [Default a]+  genum = Default . to <$> enum'++--------------------------------------------------------------------------------+-- Show+--------------------------------------------------------------------------------++-- | For example, with this type:+--+-- @+-- newtype TestShow = TestShow 'Bool'+--   deriving ('GShow') via ('Default' 'Bool')+-- @+--+-- 'gshow' for @TestShow@ would produce the same string as `gshow` for+-- 'Bool'.+--+-- In this example, @TestShow@ requires no 'Generic' instance, as the+-- constraint on 'gshowsPrec' from @'Default' 'Bool'@ is @'Generic' 'Bool'@.+--+-- In general, when using a newtype wrapper, the instance can be derived+-- via the wrapped type, as here (via @'Default' 'Bool'@ rather than @'Default'+-- TestShow@).+instance (Generic a, GShow' (Rep a)) => GShow (Default a) where+  -- gshowsPrec :: Int -> Default a -> ShowS+  gshowsPrec n (Default x) = gshowsPrecdefault n x++--------------------------------------------------------------------------------+-- Semigroup+--------------------------------------------------------------------------------++-- | Semigroups often have many sensible implementations of+-- 'Data.Semigroup.<>' / 'gsappend', and therefore no sensible default.+-- Indeed, there is no 'GSemigroup'' instance for representations of sum+-- types.+--+-- In other cases, one may wish to use the existing wrapper newtypes in+-- @base@, such as the following (using 'Data.Semigroup.First'):+--+-- @+-- newtype FirstSemigroup = FirstSemigroup 'Bool'+--   deriving stock ('Eq', 'Show')+--   deriving ('GSemigroup') via ('Data.Semigroup.First' 'Bool')+-- @+--+instance (Generic a, GSemigroup' (Rep a)) => GSemigroup (Default a) where+  -- gsappend :: Default a -> Default a -> Default a+  Default x `gsappend` Default y = Default $ x `gsappenddefault` y++--------------------------------------------------------------------------------+-- Monoid+--------------------------------------------------------------------------------++instance (Generic a, GMonoid' (Rep a)) => GMonoid (Default a) where+  -- gmempty :: Default a+  gmempty = Default gmemptydefault++  -- gmappend :: Default a -> Default a -> Default a+  Default x `gmappend` Default y = Default $ x `gmappenddefault` y++--------------------------------------------------------------------------------+-- Uniplate+--------------------------------------------------------------------------------++instance (Generic a, Uniplate' (Rep a) a, Context' (Rep a) a) => Uniplate (Default a) where++  -- children   ::                                             Default a  ->   [Default a]+  -- context    ::                             Default a   -> [Default a] ->    Default a+  -- descend    ::            (Default a ->    Default a)  ->  Default a  ->    Default a+  -- descendM   :: Monad m => (Default a -> m (Default a)) ->  Default a  -> m (Default a)+  -- transform  ::            (Default a ->    Default a)  ->  Default a  ->    Default a+  -- transformM :: Monad m => (Default a -> m (Default a)) ->  Default a  -> m (Default a)++  children     (Default x)    =       Default <$> childrendefault    x+  context      (Default x) ys =       Default  $  contextdefault     x    (unDefault <$> ys)+  descend    f (Default x)    =       Default  $  descenddefault          (unDefault . f . Default) x+  descendM   f (Default x)    = liftM Default  $  descendMdefault   (liftM unDefault . f . Default) x+  transform  f (Default x)    =       Default  $  transformdefault        (unDefault . f . Default) x+  transformM f (Default x)    = liftM Default  $  transformMdefault (liftM unDefault . f . Default) x++--------------------------------------------------------------------------------+-- Functor+--------------------------------------------------------------------------------++instance (Generic1 f, GFunctor' (Rep1 f)) => GFunctor (Default1 f) where+  -- gmap :: (a -> b) -> (Default1 f) a -> (Default1 f) b+  gmap f (Default1 fx) = Default1 $ gmapdefault f fx++--------------------------------------------------+-- Copoint+--------------------------------------------------++instance (Generic1 f, GCopoint' (Rep1 f)) => GCopoint (Default1 f) where+  -- gcopoint :: Default1 f a -> a+  gcopoint = gcopointdefault . unDefault1++--------------------------------------------------+-- Foldable+--------------------------------------------------++instance (Generic1 t, GFoldable' (Rep1 t)) => GFoldable (Default1 t) where+  -- gfoldMap :: Monoid m => (a -> m) -> Default1 t a -> m+  gfoldMap f (Default1 tx) = gfoldMapdefault f tx++--------------------------------------------------+-- Traversable+--------------------------------------------------++instance (Generic1 t, GFunctor' (Rep1 t), GFoldable' (Rep1 t), GTraversable' (Rep1 t)) => GTraversable (Default1 t) where+  -- gtraverse :: Applicative f => (a -> f b) -> Default1 t a -> f (Default1 t b)+  gtraverse f (Default1 fx) = Default1 <$> gtraversedefault f fx
src/Generics/Deriving/Enum.hs view
@@ -1,210 +1,1041 @@-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
-module Generics.Deriving.Enum (
-
-  -- * Generic enum class
-    GEnum(..)
-
-  -- * Default definitions for GEnum
-  , genumDefault, toEnumDefault, fromEnumDefault
-
-  -- * Generic Ix class
-  , GIx(..)
-
-  -- * Default definitions for GIx
-  , rangeDefault, indexDefault, inRangeDefault
-
-  ) where
-
-
-import Generics.Deriving.Base
-import Generics.Deriving.Instances ()
-import Generics.Deriving.Eq
-
-
------------------------------------------------------------------------------
--- Utility functions for Enum'
------------------------------------------------------------------------------
-
-infixr 5 |||
-
--- | Interleave elements from two lists. Similar to (++), but swap left and
--- right arguments on every recursive application.
---
--- From Mark Jones' talk at AFP2008
-(|||) :: [a] -> [a] -> [a]
-[]     ||| ys = ys
-(x:xs) ||| ys = x : ys ||| xs
-
--- | Diagonalization of nested lists. Ensure that some elements from every
--- sublist will be included. Handles infinite sublists.
---
--- From Mark Jones' talk at AFP2008
-diag :: [[a]] -> [a]
-diag = concat . foldr skew [] . map (map (\x -> [x]))
-
-skew :: [[a]] -> [[a]] -> [[a]]
-skew []     ys = ys
-skew (x:xs) ys = x : combine (++) xs ys
-
-combine :: (a -> a -> a) -> [a] -> [a] -> [a]
-combine _ xs     []     = xs
-combine _ []     ys     = ys
-combine f (x:xs) (y:ys) = f x y : combine f xs ys
-
-findIndex :: (a -> Bool) -> [a] -> Maybe Int
-findIndex p xs = let l = [ i | (y,i) <- zip xs [(0::Int)..], p y]
-                 in if (null l)
-                    then Nothing
-                    else Just (head l)
-
---------------------------------------------------------------------------------
--- Generic enum
---------------------------------------------------------------------------------
-
-class Enum' f where
-  enum' :: [f a]
-
-instance Enum' U1 where
-  enum' = [U1]
-
-instance (GEnum c) => Enum' (K1 i c) where
-  enum' = map K1 genum
-
-instance (Enum' f) => Enum' (M1 i c f) where
-  enum' = map M1 enum'
-
-instance (Enum' f, Enum' g) => Enum' (f :+: g) where
-  enum' = map L1 enum' ||| map R1 enum'
-
-instance (Enum' f, Enum' g) => Enum' (f :*: g) where
-  enum' = diag [ [ x :*: y | y <- enum' ] | x <- enum' ]
-
-
-#if __GLASGOW_HASKELL__ < 701
-
-instance (GEnum a) => GEnum (Maybe a) where
-  genum = genumDefault
-
-instance (GEnum a) => GEnum [a] where
-  genum = genumDefault
-
-#else
-
-instance (GEnum a) => GEnum (Maybe a)
-instance (GEnum a) => GEnum [a]
-
-#endif
-
-genumDefault :: (Generic a, Enum' (Rep a)) => [a]
-genumDefault = map to enum'
-
-toEnumDefault :: (Generic a, Enum' (Rep a)) => Int -> a
-toEnumDefault i = let l = enum'
-                  in if (length l > i)
-                      then to (l !! i)
-                       else error "toEnum: invalid index"
-
-fromEnumDefault :: (GEq a, Generic a, Enum' (Rep a))
-                => a -> Int
-fromEnumDefault x = case findIndex (geq x) (map to enum') of
-      Nothing -> error "fromEnum: no corresponding index"
-      Just i  -> i
-
-
-class GEnum a where
-  genum :: [a]
-
-#if __GLASGOW_HASKELL__ >= 701
-  default genum :: (Generic a, Enum' (Rep a)) => [a]
-  genum = genumDefault
-#endif
-
-instance GEnum Int where
-  genum = [0..] ||| (neg 0) where
-    neg n = (n-1) : neg (n-1)
-
---------------------------------------------------------------------------------
--- Generic Ix
---------------------------------------------------------------------------------
-
--- Minimal complete instance: 'range', 'index' and 'inRange'.
-class (Ord a) => GIx a where
-    -- | The list of values in the subrange defined by a bounding pair.
-    range               :: (a,a) -> [a]
-    -- | The position of a subscript in the subrange.
-    index               :: (a,a) -> a -> Int
-    -- | Returns 'True' the given subscript lies in the range defined
-    -- the bounding pair.
-    inRange             :: (a,a) -> a -> Bool
-#if __GLASGOW_HASKELL__ >= 701
-    default range :: (GEq a, Generic a, Enum' (Rep a)) => (a,a) -> [a]
-    range = rangeDefault
-
-    default index :: (GEq a, Generic a, Enum' (Rep a)) => (a,a) -> a -> Int
-    index = indexDefault
-
-    default inRange :: (GEq a, Generic a, Enum' (Rep a)) => (a,a) -> a -> Bool
-    inRange = inRangeDefault
-#endif
-
-rangeDefault :: (GEq a, Generic a, Enum' (Rep a))
-             => (a,a) -> [a]
-rangeDefault = t (map to enum') where
-  t l (x,y) = 
-    case (findIndex (geq x) l, findIndex (geq y) l) of
-      (Nothing, _)     -> error "rangeDefault: no corresponding index"
-      (_, Nothing)     -> error "rangeDefault: no corresponding index"
-      (Just i, Just j) -> take (j-i) (drop i l)
-
-indexDefault :: (GEq a, Generic a, Enum' (Rep a))
-             => (a,a) -> a -> Int
-indexDefault = t (map to enum') where
-  t l (x,y) z =
-    case (findIndex (geq x) l, findIndex (geq y) l) of
-      (Nothing, _)     -> error "indexDefault: no corresponding index"
-      (_, Nothing)     -> error "indexDefault: no corresponding index"
-      (Just i, Just j) -> case findIndex (geq z) (take (j-i) (drop i l)) of
-                            Nothing -> error "indexDefault: index out of range"
-                            Just k  -> k
-
-inRangeDefault :: (GEq a, Generic a, Enum' (Rep a))
-               => (a,a) -> a -> Bool
-inRangeDefault = t (map to enum') where
-  t l (x,y) z = 
-    case (findIndex (geq x) l, findIndex (geq y) l) of
-      (Nothing, _)     -> error "indexDefault: no corresponding index"
-      (_, Nothing)     -> error "indexDefault: no corresponding index"
-      (Just i, Just j) -> maybe False (const True)
-                            (findIndex (geq z) (take (j-i) (drop i l)))
-
-#if __GLASGOW_HASKELL__ < 701
-
-instance (GEq a, GEnum a, GIx a) => GIx (Maybe a) where
-  range = rangeDefault
-  index = indexDefault
-  inRange = inRangeDefault
-
-instance (GEq a, GEnum a, GIx a) => GIx [a] where
-  range = rangeDefault
-  index = indexDefault
-  inRange = inRangeDefault
-
-#else
-
-instance (GEq a, GEnum a, GIx a) => GIx (Maybe a)
-instance (GEq a, GEnum a, GIx a) => GIx [a]
-
-#endif
-
-instance GIx Int where
-    range (m,n) = [m..n]
-    index (m,_n) i = i - m
-    inRange (m,n) i =  m <= i && i <= n
+{-# LANGUAGE CPP #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++#include "HsBaseConfig.h"++module Generics.Deriving.Enum (++  -- * Generic enum class+    GEnum(..)++  -- * Default definitions for GEnum+  , genumDefault, toEnumDefault, fromEnumDefault++  -- * Internal enum class+  , Enum'(..)++  -- * Generic Ix class+  , GIx(..)++  -- * Default definitions for GIx+  , rangeDefault, indexDefault, inRangeDefault++  ) where++import           Control.Applicative (Const, ZipList)++import           Data.Coerce (coerce)+import           Data.Complex (Complex)+import           Data.Functor.Identity (Identity)+import           Data.Int+import           Data.List.NonEmpty (NonEmpty)+import           Data.Maybe (listToMaybe)+import           Data.Monoid (All, Alt, Any, Dual, Product, Sum)+import qualified Data.Monoid as Monoid (First, Last)+import           Data.Proxy (Proxy)+import qualified Data.Semigroup as Semigroup (First, Last)+import           Data.Semigroup (Arg, Max, Min, WrappedMonoid)+import           Data.Word++import           Foreign.C.Types+import           Foreign.Ptr++import           Generics.Deriving.Base+import           Generics.Deriving.Eq++import           Numeric.Natural (Natural)++import           System.Exit (ExitCode)+import           System.Posix.Types++-----------------------------------------------------------------------------+-- Utility functions for Enum'+-----------------------------------------------------------------------------++infixr 5 |||++-- | Interleave elements from two lists. Similar to (++), but swap left and+-- right arguments on every recursive application.+--+-- From Mark Jones' talk at AFP2008+(|||) :: [a] -> [a] -> [a]+[]     ||| ys = ys+(x:xs) ||| ys = x : ys ||| xs++-- | Diagonalization of nested lists. Ensure that some elements from every+-- sublist will be included. Handles infinite sublists.+--+-- From Mark Jones' talk at AFP2008+diag :: [[a]] -> [a]+diag = concat . foldr skew [] . map (map (\x -> [x]))++skew :: [[a]] -> [[a]] -> [[a]]+skew []     ys = ys+skew (x:xs) ys = x : combine (++) xs ys++combine :: (a -> a -> a) -> [a] -> [a] -> [a]+combine _ xs     []     = xs+combine _ []     ys     = ys+combine f (x:xs) (y:ys) = f x y : combine f xs ys++findIndex :: (a -> Bool) -> [a] -> Maybe Int+findIndex p xs = let l = [ i | (y,i) <- zip xs [(0::Int)..], p y]+                 in listToMaybe l++--------------------------------------------------------------------------------+-- Generic enum+--------------------------------------------------------------------------------++class Enum' f where+  enum' :: [f a]++instance Enum' U1 where+  enum' = [U1]++instance (GEnum c) => Enum' (K1 i c) where+  enum' = map K1 genum++instance (Enum' f) => Enum' (M1 i c f) where+  enum' = map M1 enum'++instance (Enum' f, Enum' g) => Enum' (f :+: g) where+  enum' = map L1 enum' ||| map R1 enum'++instance (Enum' f, Enum' g) => Enum' (f :*: g) where+  enum' = diag [ [ x :*: y | y <- enum' ] | x <- enum' ]++genumDefault :: (Generic a, Enum' (Rep a)) => [a]+genumDefault = map to enum'++toEnumDefault :: (Generic a, Enum' (Rep a)) => Int -> a+toEnumDefault i = let l = enum'+                  in if (length l > i)+                      then to (l !! i)+                       else error "toEnum: invalid index"++fromEnumDefault :: (GEq a, Generic a, Enum' (Rep a))+                => a -> Int+fromEnumDefault x = case findIndex (geq x) (map to enum') of+      Nothing -> error "fromEnum: no corresponding index"+      Just i  -> i+++class GEnum a where+  genum :: [a]++  default genum :: (Generic a, Enum' (Rep a)) => [a]+  genum = genumDefault++genumNumUnbounded :: Num a => [a]+genumNumUnbounded = pos 0 ||| neg 0 where+  pos n = n     : pos (n + 1)+  neg n = (n-1) : neg (n - 1)++genumNumSigned :: (Bounded a, Enum a, Num a) => [a]+genumNumSigned = [0 .. maxBound] ||| [-1, -2 .. minBound]++genumNumUnsigned :: (Enum a, Num a) => [a]+genumNumUnsigned = [0 ..]++-- Base types instances+instance GEnum () where+  genum = genumDefault++instance (GEnum a, GEnum b) => GEnum (a, b) where+  genum = genumDefault++instance (GEnum a, GEnum b, GEnum c) => GEnum (a, b, c) where+  genum = genumDefault++instance (GEnum a, GEnum b, GEnum c, GEnum d) => GEnum (a, b, c, d) where+  genum = genumDefault++instance (GEnum a, GEnum b, GEnum c, GEnum d, GEnum e) => GEnum (a, b, c, d, e) where+  genum = genumDefault++instance (GEnum a, GEnum b, GEnum c, GEnum d, GEnum e, GEnum f)+    => GEnum (a, b, c, d, e, f) where+  genum = genumDefault++instance (GEnum a, GEnum b, GEnum c, GEnum d, GEnum e, GEnum f, GEnum g)+    => GEnum (a, b, c, d, e, f, g) where+  genum = genumDefault++instance GEnum a => GEnum [a] where+  genum = genumDefault++instance (GEnum (f p), GEnum (g p)) => GEnum ((f :+: g) p) where+  genum = genumDefault++instance (GEnum (f p), GEnum (g p)) => GEnum ((f :*: g) p) where+  genum = genumDefault++instance GEnum (f (g p)) => GEnum ((f :.: g) p) where+  genum = genumDefault++instance GEnum All where+  genum = genumDefault++instance GEnum (f a) => GEnum (Alt f a) where+  genum = genumDefault++instance GEnum Any where+  genum = genumDefault++instance (GEnum a, GEnum b) => GEnum (Arg a b) where+  genum = genumDefault++instance GEnum Associativity where+  genum = genumDefault++instance GEnum Bool where+  genum = genumDefault++#if defined(HTYPE_CC_T)+instance GEnum CCc where+  genum = coerce (genum :: [HTYPE_CC_T])+#endif++instance GEnum CChar where+  genum = coerce (genum :: [HTYPE_CHAR])++instance GEnum CClock where+  genum = coerce (genum :: [HTYPE_CLOCK_T])++#if defined(HTYPE_DEV_T)+instance GEnum CDev where+  genum = coerce (genum :: [HTYPE_DEV_T])+#endif++instance GEnum CDouble where+  genum = coerce (genum :: [HTYPE_DOUBLE])++instance GEnum CFloat where+  genum = coerce (genum :: [HTYPE_FLOAT])++#if defined(HTYPE_GID_T)+instance GEnum CGid where+  genum = coerce (genum :: [HTYPE_GID_T])+#endif++#if defined(HTYPE_INO_T)+instance GEnum CIno where+  genum = coerce (genum :: [HTYPE_INO_T])+#endif++instance GEnum CInt where+  genum = coerce (genum :: [HTYPE_INT])++instance GEnum CIntMax where+  genum = coerce (genum :: [HTYPE_INTMAX_T])++instance GEnum CIntPtr where+  genum = coerce (genum :: [HTYPE_INTPTR_T])++instance GEnum CLLong where+  genum = coerce (genum :: [HTYPE_LONG_LONG])++instance GEnum CLong where+  genum = coerce (genum :: [HTYPE_LONG])++#if defined(HTYPE_MODE_T)+instance GEnum CMode where+  genum = coerce (genum :: [HTYPE_MODE_T])+#endif++#if defined(HTYPE_NLINK_T)+instance GEnum CNlink where+  genum = coerce (genum :: [HTYPE_NLINK_T])+#endif++#if defined(HTYPE_OFF_T)+instance GEnum COff where+  genum = coerce (genum :: [HTYPE_OFF_T])+#endif++instance GEnum a => GEnum (Complex a) where+  genum = genumDefault++instance GEnum a => GEnum (Const a b) where+  genum = genumDefault++#if defined(HTYPE_PID_T)+instance GEnum CPid where+  genum = coerce (genum :: [HTYPE_PID_T])+#endif++instance GEnum CPtrdiff where+  genum = coerce (genum :: [HTYPE_PTRDIFF_T])++#if defined(HTYPE_RLIM_T)+instance GEnum CRLim where+  genum = coerce (genum :: [HTYPE_RLIM_T])+#endif++instance GEnum CSChar where+  genum = coerce (genum :: [HTYPE_SIGNED_CHAR])++#if defined(HTYPE_SPEED_T)+instance GEnum CSpeed where+  genum = coerce (genum :: [HTYPE_SPEED_T])+#endif++instance GEnum CSUSeconds where+  genum = coerce (genum :: [HTYPE_SUSECONDS_T])++instance GEnum CShort where+  genum = coerce (genum :: [HTYPE_SHORT])++instance GEnum CSigAtomic where+#if defined(HTYPE_SIG_ATOMIC_T)+  genum = coerce (genum :: [HTYPE_SIG_ATOMIC_T])+#else+  genum = coerce (genum :: [Int32])+#endif++instance GEnum CSize where+  genum = coerce (genum :: [HTYPE_SIZE_T])++#if defined(HTYPE_SSIZE_T)+instance GEnum CSsize where+  genum = coerce (genum :: [HTYPE_SSIZE_T])+#endif++#if defined(HTYPE_TCFLAG_T)+instance GEnum CTcflag where+  genum = coerce (genum :: [HTYPE_TCFLAG_T])+#endif++instance GEnum CTime where+  genum = coerce (genum :: [HTYPE_TIME_T])++instance GEnum CUChar where+  genum = coerce (genum :: [HTYPE_UNSIGNED_CHAR])++#if defined(HTYPE_UID_T)+instance GEnum CUid where+  genum = coerce (genum :: [HTYPE_UID_T])+#endif++instance GEnum CUInt where+  genum = coerce (genum :: [HTYPE_UNSIGNED_INT])++instance GEnum CUIntMax where+  genum = coerce (genum :: [HTYPE_UINTMAX_T])++instance GEnum CUIntPtr where+  genum = coerce (genum :: [HTYPE_UINTPTR_T])++instance GEnum CULLong where+  genum = coerce (genum :: [HTYPE_UNSIGNED_LONG_LONG])++instance GEnum CULong where+  genum = coerce (genum :: [HTYPE_UNSIGNED_LONG])++instance GEnum CUSeconds where+  genum = coerce (genum :: [HTYPE_USECONDS_T])++instance GEnum CUShort where+  genum = coerce (genum :: [HTYPE_UNSIGNED_SHORT])++instance GEnum CWchar where+  genum = coerce (genum :: [HTYPE_WCHAR_T])++instance GEnum Double where+  genum = genumNumUnbounded++instance GEnum a => GEnum (Dual a) where+  genum = genumDefault++instance (GEnum a, GEnum b) => GEnum (Either a b) where+  genum = genumDefault++instance GEnum ExitCode where+  genum = genumDefault++instance GEnum Fd where+  genum = coerce (genum :: [CInt])++instance GEnum a => GEnum (Monoid.First a) where+  genum = genumDefault++instance GEnum a => GEnum (Semigroup.First a) where+  genum = genumDefault++instance GEnum Fixity where+  genum = genumDefault++instance GEnum Float where+  genum = genumNumUnbounded++instance GEnum a => GEnum (Identity a) where+  genum = genumDefault++instance GEnum Int where+  genum = genumNumSigned++instance GEnum Int8 where+  genum = genumNumSigned++instance GEnum Int16 where+  genum = genumNumSigned++instance GEnum Int32 where+  genum = genumNumSigned++instance GEnum Int64 where+  genum = genumNumSigned++instance GEnum Integer where+  genum = genumNumUnbounded++instance GEnum IntPtr where+  genum = genumNumSigned++instance GEnum c => GEnum (K1 i c p) where+  genum = genumDefault++instance GEnum a => GEnum (Monoid.Last a) where+  genum = genumDefault++instance GEnum a => GEnum (Semigroup.Last a) where+  genum = genumDefault++instance GEnum (f p) => GEnum (M1 i c f p) where+  genum = genumDefault++instance GEnum a => GEnum (Max a) where+  genum = genumDefault++instance GEnum a => GEnum (Maybe a) where+  genum = genumDefault++instance GEnum a => GEnum (Min a) where+  genum = genumDefault++instance GEnum Natural where+  genum = genumNumUnsigned++instance GEnum a => GEnum (NonEmpty a) where+  genum = genumDefault++instance GEnum Ordering where+  genum = genumDefault++instance GEnum p => GEnum (Par1 p) where+  genum = genumDefault++instance GEnum a => GEnum (Product a) where+  genum = genumDefault++instance GEnum (Proxy s) where+  genum = genumDefault++instance GEnum (f p) => GEnum (Rec1 f p) where+  genum = genumDefault++instance GEnum a => GEnum (Sum a) where+  genum = genumDefault++instance GEnum (U1 p) where+  genum = genumDefault++instance GEnum Word where+  genum = genumNumUnsigned++instance GEnum Word8 where+  genum = genumNumUnsigned++instance GEnum Word16 where+  genum = genumNumUnsigned++instance GEnum Word32 where+  genum = genumNumUnsigned++instance GEnum Word64 where+  genum = genumNumUnsigned++instance GEnum WordPtr where+  genum = genumNumUnsigned++instance GEnum m => GEnum (WrappedMonoid m) where+  genum = genumDefault++instance GEnum a => GEnum (ZipList a) where+  genum = genumDefault++#if MIN_VERSION_base(4,10,0)+instance GEnum CBool where+  genum = coerce (genum :: [HTYPE_BOOL])++# if defined(HTYPE_BLKSIZE_T)+instance GEnum CBlkSize where+  genum = coerce (genum :: [HTYPE_BLKSIZE_T])+# endif++# if defined(HTYPE_BLKCNT_T)+instance GEnum CBlkCnt where+  genum = coerce (genum :: [HTYPE_BLKCNT_T])+# endif++# if defined(HTYPE_CLOCKID_T)+instance GEnum CClockId where+  genum = coerce (genum :: [HTYPE_CLOCKID_T])+# endif++# if defined(HTYPE_FSBLKCNT_T)+instance GEnum CFsBlkCnt where+  genum = coerce (genum :: [HTYPE_FSBLKCNT_T])+# endif++# if defined(HTYPE_FSFILCNT_T)+instance GEnum CFsFilCnt where+  genum = coerce (genum :: [HTYPE_FSFILCNT_T])+# endif++# if defined(HTYPE_ID_T)+instance GEnum CId where+  genum = coerce (genum :: [HTYPE_ID_T])+# endif++# if defined(HTYPE_KEY_T)+instance GEnum CKey where+  genum = coerce (genum :: [HTYPE_KEY_T])+# endif+#endif++--------------------------------------------------------------------------------+-- Generic Ix+--------------------------------------------------------------------------------++-- Minimal complete instance: 'range', 'index' and 'inRange'.+class (Ord a) => GIx a where+    -- | The list of values in the subrange defined by a bounding pair.+    range               :: (a,a) -> [a]+    -- | The position of a subscript in the subrange.+    index               :: (a,a) -> a -> Int+    -- | Returns 'True' the given subscript lies in the range defined+    -- the bounding pair.+    inRange             :: (a,a) -> a -> Bool++    default range :: (GEq a, Generic a, Enum' (Rep a)) => (a,a) -> [a]+    range = rangeDefault++    default index :: (GEq a, Generic a, Enum' (Rep a)) => (a,a) -> a -> Int+    index = indexDefault++    default inRange :: (GEq a, Generic a, Enum' (Rep a)) => (a,a) -> a -> Bool+    inRange = inRangeDefault++rangeDefault :: (GEq a, Generic a, Enum' (Rep a))+             => (a,a) -> [a]+rangeDefault = t (map to enum') where+  t l (x,y) =+    case (findIndex (geq x) l, findIndex (geq y) l) of+      (Nothing, _)     -> error "rangeDefault: no corresponding index"+      (_, Nothing)     -> error "rangeDefault: no corresponding index"+      (Just i, Just j) -> take (j-i) (drop i l)++indexDefault :: (GEq a, Generic a, Enum' (Rep a))+             => (a,a) -> a -> Int+indexDefault = t (map to enum') where+  t l (x,y) z =+    case (findIndex (geq x) l, findIndex (geq y) l) of+      (Nothing, _)     -> error "indexDefault: no corresponding index"+      (_, Nothing)     -> error "indexDefault: no corresponding index"+      (Just i, Just j) -> case findIndex (geq z) (take (j-i) (drop i l)) of+                            Nothing -> error "indexDefault: index out of range"+                            Just k  -> k++inRangeDefault :: (GEq a, Generic a, Enum' (Rep a))+               => (a,a) -> a -> Bool+inRangeDefault = t (map to enum') where+  t l (x,y) z =+    case (findIndex (geq x) l, findIndex (geq y) l) of+      (Nothing, _)     -> error "indexDefault: no corresponding index"+      (_, Nothing)     -> error "indexDefault: no corresponding index"+      (Just i, Just j) -> maybe False (const True)+                            (findIndex (geq z) (take (j-i) (drop i l)))++rangeEnum :: Enum a => (a, a) -> [a]+rangeEnum (m,n) = [m..n]++indexIntegral :: Integral a => (a, a) -> a -> Int+indexIntegral (m,_n) i = fromIntegral (i - m)++inRangeOrd :: Ord a => (a, a) -> a -> Bool+inRangeOrd (m,n) i =  m <= i && i <= n++-- Base types instances+instance GIx () where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEq b, GEnum b, GIx b) => GIx (a, b) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEq b, GEnum b, GIx b, GEq c, GEnum c, GIx c)+    => GIx (a, b, c) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEq b, GEnum b, GIx b, GEq c, GEnum c, GIx c,+          GEq d, GEnum d, GIx d)+    => GIx (a, b, c, d) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEq b, GEnum b, GIx b, GEq c, GEnum c, GIx c,+          GEq d, GEnum d, GIx d, GEq e, GEnum e, GIx e)+    => GIx (a, b, c, d, e) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEq b, GEnum b, GIx b, GEq c, GEnum c, GIx c,+          GEq d, GEnum d, GIx d, GEq e, GEnum e, GIx e, GEq f, GEnum f, GIx f)+    => GIx (a, b, c, d, e, f) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEq b, GEnum b, GIx b, GEq c, GEnum c, GIx c,+          GEq d, GEnum d, GIx d, GEq e, GEnum e, GIx e, GEq f, GEnum f, GIx f,+          GEq g, GEnum g, GIx g)+    => GIx (a, b, c, d, e, f, g) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx [a] where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx All where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq (f a), GEnum (f a), GIx (f a)) => GIx (Alt f a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Any where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEnum b) => GIx (Arg a b) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Associativity where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Bool where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx CChar where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++#if defined(HTYPE_GID_T)+instance GIx CGid where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++#if defined(HTYPE_INO_T)+instance GIx CIno where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++instance GIx CInt where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CIntMax where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CIntPtr where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CLLong where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CLong where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++#if defined(HTYPE_MODE_T)+instance GIx CMode where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++#if defined(HTYPE_NLINK_T)+instance GIx CNlink where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++#if defined(HTYPE_OFF_T)+instance GIx COff where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++#if defined(HTYPE_PID_T)+instance GIx CPid where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++instance GIx CPtrdiff where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++#if defined(HTYPE_RLIM_T)+instance GIx CRLim where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++instance GIx CSChar where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CShort where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CSigAtomic where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CSize where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++#if defined(HTYPE_SSIZE_T)+instance GIx CSsize where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++#if defined(HTYPE_TCFLAG_T)+instance GIx CTcflag where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++instance GIx CUChar where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++#if defined(HTYPE_UID_T)+instance GIx CUid where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+#endif++instance GIx CUInt where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CUIntMax where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CUIntPtr where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CULLong where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CULong where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CUShort where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx CWchar where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance (GEq a, GEnum a, GIx a) => GIx (Dual a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a, GEq b, GEnum b, GIx b) => GIx (Either a b) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx ExitCode where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Fd where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance (GEq a, GEnum a, GIx a) => GIx (Monoid.First a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Semigroup.First a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Fixity where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Identity a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Int where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Int8 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Int16 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Int32 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Int64 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Integer where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx IntPtr where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance (GEq a, GEnum a, GIx a) => GIx (Monoid.Last a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Semigroup.Last a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Max a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Maybe a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Min a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Natural where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance (GEq a, GEnum a, GIx a) => GIx (NonEmpty a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Ordering where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Product a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx (Proxy s) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance (GEq a, GEnum a, GIx a) => GIx (Sum a) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++instance GIx Word where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Word8 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Word16 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Word32 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx Word64 where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance GIx WordPtr where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++instance (GEq m, GEnum m, GIx m) => GIx (WrappedMonoid m) where+  range   = rangeDefault+  index   = indexDefault+  inRange = inRangeDefault++#if MIN_VERSION_base(4,10,0)+instance GIx CBool where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd++# if defined(HTYPE_BLKSIZE_T)+instance GIx CBlkSize where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+# endif++# if defined(HTYPE_BLKCNT_T)+instance GIx CBlkCnt where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+# endif++# if defined(HTYPE_CLOCKID_T)+instance GIx CClockId where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+# endif++# if defined(HTYPE_FSBLKCNT_T)+instance GIx CFsBlkCnt where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+# endif++# if defined(HTYPE_FSFILCNT_T)+instance GIx CFsFilCnt where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+# endif++# if defined(HTYPE_ID_T)+instance GIx CId where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+# endif++# if defined(HTYPE_KEY_T)+instance GIx CKey where+  range   = rangeEnum+  index   = indexIntegral+  inRange = inRangeOrd+# endif+#endif
src/Generics/Deriving/Eq.hs view
@@ -1,93 +1,557 @@-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE CPP #-}
-
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
-
-module Generics.Deriving.Eq (
-  -- * Generic show class
-    GEq(..)
-
-#if __GLASGOW_HASKELL__ >= 701
--- Nothing
-#else
-  -- * Default definition
-  , geqdefault
-#endif
-
-  ) where
-
-
-import Generics.Deriving.Base
-import Generics.Deriving.Instances ()
--- import GHC.Generics
-
---------------------------------------------------------------------------------
--- Generic show
---------------------------------------------------------------------------------
-
-class GEq' f where
-  geq' :: f a -> f a -> Bool
-
-instance GEq' U1 where
-  geq' _ _ = True
-
-instance (GEq c) => GEq' (K1 i c) where
-  geq' (K1 a) (K1 b) = geq a b
-
--- No instances for P or Rec because geq is only applicable to types of kind *
-
-instance (GEq' a) => GEq' (M1 i c a) where
-  geq' (M1 a) (M1 b) = geq' a b
-
-instance (GEq' a, GEq' b) => GEq' (a :+: b) where
-  geq' (L1 a) (L1 b) = geq' a b
-  geq' (R1 a) (R1 b) = geq' a b
-  geq' _      _      = False
-
-instance (GEq' a, GEq' b) => GEq' (a :*: b) where
-  geq' (a1 :*: b1) (a2 :*: b2) = geq' a1 a2 && geq' b1 b2
-
-
-class GEq a where 
-  geq :: a -> a -> Bool
-
-
-#if __GLASGOW_HASKELL__ >= 701
-  default geq :: (Generic a, GEq' (Rep a)) => a -> a -> Bool
-  geq x y = geq' (from x) (from y)
-#endif
-
-#if __GLASGOW_HASKELL__ >= 701
--- Nothing; the default is in the class
-#else
-geqdefault :: (Generic a, GEq' (Rep a)) => a -> a -> Bool
-geqdefault x y = geq' (from x) (from y)
-#endif
-
--- Base types instances
-instance GEq Char   where geq = (==)
-instance GEq Int    where geq = (==)
-instance GEq Float  where geq = (==)
-
-
-#if __GLASGOW_HASKELL__ < 701
-
-instance (GEq a) => GEq (Maybe a) where
-  geq = geqdefault
-
-instance (GEq a) => GEq [a] where
-  geq = geqdefault
-
-#else
-
-instance (GEq a) => GEq (Maybe a)
-instance (GEq a) => GEq [a]
-
-#endif
+{-# LANGUAGE CPP #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MagicHash #-}++#include "HsBaseConfig.h"++module Generics.Deriving.Eq (+  -- * Generic Eq class+    GEq(..)++  -- * Default definition+  , geqdefault++  -- * Internal Eq class+  , GEq'(..)++  ) where++import           Control.Applicative (Const, ZipList)++import           Data.Char (GeneralCategory)+import           Data.Complex (Complex)+import           Data.Functor.Identity (Identity)+import           Data.Int+import           Data.List.NonEmpty (NonEmpty)+import qualified Data.Monoid as Monoid (First, Last)+import           Data.Monoid (All, Alt, Any, Dual, Product, Sum)+import           Data.Proxy (Proxy)+import qualified Data.Semigroup as Semigroup (First, Last)+import           Data.Semigroup (Arg(..), Max, Min, WrappedMonoid)+import           Data.Version (Version)+import           Data.Void (Void)+import           Data.Word++import           Foreign.C.Error+import           Foreign.C.Types+import           Foreign.ForeignPtr (ForeignPtr)+import           Foreign.Ptr+import           Foreign.StablePtr (StablePtr)++import           Generics.Deriving.Base++import           GHC.Exts hiding (Any)++import           Numeric.Natural (Natural)++import           System.Exit (ExitCode)+import           System.IO (BufferMode, Handle, HandlePosn, IOMode, SeekMode)+import           System.IO.Error (IOErrorType)+import           System.Posix.Types++--------------------------------------------------------------------------------+-- Generic show+--------------------------------------------------------------------------------++class GEq' f where+  geq' :: f a -> f a -> Bool++instance GEq' V1 where+  geq' _ _ = True++instance GEq' U1 where+  geq' _ _ = True++instance (GEq c) => GEq' (K1 i c) where+  geq' (K1 a) (K1 b) = geq a b++-- No instances for P or Rec because geq is only applicable to types of kind *++instance (GEq' a) => GEq' (M1 i c a) where+  geq' (M1 a) (M1 b) = geq' a b++instance (GEq' a, GEq' b) => GEq' (a :+: b) where+  geq' (L1 a) (L1 b) = geq' a b+  geq' (R1 a) (R1 b) = geq' a b+  geq' _      _      = False++instance (GEq' a, GEq' b) => GEq' (a :*: b) where+  geq' (a1 :*: b1) (a2 :*: b2) = geq' a1 a2 && geq' b1 b2++-- Unboxed types+instance GEq' UAddr where+  geq' (UAddr a1) (UAddr a2)     = isTrue# (eqAddr# a1 a2)+instance GEq' UChar where+  geq' (UChar c1) (UChar c2)     = isTrue# (eqChar# c1 c2)+instance GEq' UDouble where+  geq' (UDouble d1) (UDouble d2) = isTrue# (d1 ==## d2)+instance GEq' UFloat where+  geq' (UFloat f1) (UFloat f2)   = isTrue# (eqFloat# f1 f2)+instance GEq' UInt where+  geq' (UInt i1) (UInt i2)       = isTrue# (i1 ==# i2)+instance GEq' UWord where+  geq' (UWord w1) (UWord w2)     = isTrue# (eqWord# w1 w2)+++class GEq a where+  geq :: a -> a -> Bool++  default geq :: (Generic a, GEq' (Rep a)) => a -> a -> Bool+  geq = geqdefault++geqdefault :: (Generic a, GEq' (Rep a)) => a -> a -> Bool+geqdefault x y = geq' (from x) (from y)++-- Base types instances+instance GEq () where+  geq = geqdefault++instance (GEq a, GEq b) => GEq (a, b) where+  geq = geqdefault++instance (GEq a, GEq b, GEq c) => GEq (a, b, c) where+  geq = geqdefault++instance (GEq a, GEq b, GEq c, GEq d) => GEq (a, b, c, d) where+  geq = geqdefault++instance (GEq a, GEq b, GEq c, GEq d, GEq e) => GEq (a, b, c, d, e) where+  geq = geqdefault++instance (GEq a, GEq b, GEq c, GEq d, GEq e, GEq f)+    => GEq (a, b, c, d, e, f) where+  geq = geqdefault++instance (GEq a, GEq b, GEq c, GEq d, GEq e, GEq f, GEq g)+    => GEq (a, b, c, d, e, f, g) where+  geq = geqdefault++instance GEq a => GEq [a] where+  geq = geqdefault++instance (GEq (f p), GEq (g p)) => GEq ((f :+: g) p) where+  geq = geqdefault++instance (GEq (f p), GEq (g p)) => GEq ((f :*: g) p) where+  geq = geqdefault++instance GEq (f (g p)) => GEq ((f :.: g) p) where+  geq = geqdefault++instance GEq All where+  geq = geqdefault++instance GEq (f a) => GEq (Alt f a) where+  geq = geqdefault++instance GEq Any where+  geq = geqdefault++instance GEq a => GEq (Arg a b) where+  geq (Arg a _) (Arg b _) = geq a b++instance GEq Associativity where+  geq = geqdefault++instance GEq Bool where+  geq = geqdefault++instance GEq BufferMode where+  geq = (==)++#if defined(HTYPE_CC_T)+instance GEq CCc where+  geq = (==)+#endif++instance GEq CChar where+  geq = (==)++instance GEq CClock where+  geq = (==)++#if defined(HTYPE_DEV_T)+instance GEq CDev where+  geq = (==)+#endif++instance GEq CDouble where+  geq = (==)++instance GEq CFloat where+  geq = (==)++#if defined(HTYPE_GID_T)+instance GEq CGid where+  geq = (==)+#endif++instance GEq Char where+  geq = (==)++#if defined(HTYPE_INO_T)+instance GEq CIno where+  geq = (==)+#endif++instance GEq CInt where+  geq = (==)++instance GEq CIntMax where+  geq = (==)++instance GEq CIntPtr where+  geq = (==)++instance GEq CLLong where+  geq = (==)++instance GEq CLong where+  geq = (==)++#if defined(HTYPE_MODE_T)+instance GEq CMode where+  geq = (==)+#endif++#if defined(HTYPE_NLINK_T)+instance GEq CNlink where+  geq = (==)+#endif++#if defined(HTYPE_OFF_T)+instance GEq COff where+  geq = (==)+#endif++instance GEq a => GEq (Complex a) where+  geq = geqdefault++instance GEq a => GEq (Const a b) where+  geq = geqdefault++#if defined(HTYPE_PID_T)+instance GEq CPid where+  geq = (==)+#endif++instance GEq CPtrdiff where+  geq = (==)++#if defined(HTYPE_RLIM_T)+instance GEq CRLim where+  geq = (==)+#endif++instance GEq CSChar where+  geq = (==)++#if defined(HTYPE_SPEED_T)+instance GEq CSpeed where+  geq = (==)+#endif++instance GEq CSUSeconds where+  geq = (==)++instance GEq CShort where+  geq = (==)++instance GEq CSigAtomic where+  geq = (==)++instance GEq CSize where+  geq = (==)++#if defined(HTYPE_SSIZE_T)+instance GEq CSsize where+  geq = (==)+#endif++#if defined(HTYPE_TCFLAG_T)+instance GEq CTcflag where+  geq = (==)+#endif++instance GEq CTime where+  geq = (==)++instance GEq CUChar where+  geq = (==)++#if defined(HTYPE_UID_T)+instance GEq CUid where+  geq = (==)+#endif++instance GEq CUInt where+  geq = (==)++instance GEq CUIntMax where+  geq = (==)++instance GEq CUIntPtr where+  geq = (==)++instance GEq CULLong where+  geq = (==)++instance GEq CULong where+  geq = (==)++instance GEq CUSeconds where+  geq = (==)++instance GEq CUShort where+  geq = (==)++instance GEq CWchar where+  geq = (==)++instance GEq DecidedStrictness where+  geq = geqdefault++instance GEq Double where+  geq = (==)++instance GEq a => GEq (Down a) where+  geq = geqdefault++instance GEq a => GEq (Dual a) where+  geq = geqdefault++instance (GEq a, GEq b) => GEq (Either a b) where+  geq = geqdefault++instance GEq Errno where+  geq = (==)++instance GEq ExitCode where+  geq = geqdefault++instance GEq Fd where+  geq = (==)++instance GEq a => GEq (Monoid.First a) where+  geq = geqdefault++instance GEq a => GEq (Semigroup.First a) where+  geq = geqdefault++instance GEq Fixity where+  geq = geqdefault++instance GEq Float where+  geq = (==)++instance GEq (ForeignPtr a) where+  geq = (==)++instance GEq (FunPtr a) where+  geq = (==)++instance GEq GeneralCategory where+  geq = (==)++instance GEq Handle where+  geq = (==)++instance GEq HandlePosn where+  geq = (==)++instance GEq a => GEq (Identity a) where+  geq = geqdefault++instance GEq Int where+  geq = (==)++instance GEq Int8 where+  geq = (==)++instance GEq Int16 where+  geq = (==)++instance GEq Int32 where+  geq = (==)++instance GEq Int64 where+  geq = (==)++instance GEq Integer where+  geq = (==)++instance GEq IntPtr where+  geq = (==)++instance GEq IOError where+  geq = (==)++instance GEq IOErrorType where+  geq = (==)++instance GEq IOMode where+  geq = (==)++instance GEq c => GEq (K1 i c p) where+  geq = geqdefault++instance GEq a => GEq (Monoid.Last a) where+  geq = geqdefault++instance GEq a => GEq (Semigroup.Last a) where+  geq = geqdefault++instance GEq (f p) => GEq (M1 i c f p) where+  geq = geqdefault++instance GEq a => GEq (Maybe a) where+  geq = geqdefault++instance GEq a => GEq (Max a) where+  geq = geqdefault++instance GEq a => GEq (Min a) where+  geq = geqdefault++instance GEq Natural where+  geq = (==)++instance GEq a => GEq (NonEmpty a) where+  geq = geqdefault++instance GEq Ordering where+  geq = geqdefault++instance GEq p => GEq (Par1 p) where+  geq = geqdefault++instance GEq a => GEq (Product a) where+  geq = geqdefault++instance GEq (Proxy s) where+  geq = geqdefault++instance GEq (Ptr a) where+  geq = (==)++instance GEq (f p) => GEq (Rec1 f p) where+  geq = geqdefault++instance GEq SeekMode where+  geq = (==)++instance GEq (StablePtr a) where+  geq = (==)++instance GEq SourceStrictness where+  geq = geqdefault++instance GEq SourceUnpackedness where+  geq = geqdefault++instance GEq a => GEq (Sum a) where+  geq = geqdefault++instance GEq (U1 p) where+  geq = geqdefault++instance GEq (UAddr p) where+  geq = geqdefault++instance GEq (UChar p) where+  geq = geqdefault++instance GEq (UDouble p) where+  geq = geqdefault++instance GEq (UFloat p) where+  geq = geqdefault++instance GEq (UInt p) where+  geq = geqdefault++instance GEq (UWord p) where+  geq = geqdefault++instance GEq Version where+  geq = (==)++instance GEq Void where+  geq = (==)++instance GEq Word where+  geq = (==)++instance GEq Word8 where+  geq = (==)++instance GEq Word16 where+  geq = (==)++instance GEq Word32 where+  geq = (==)++instance GEq Word64 where+  geq = (==)++instance GEq WordPtr where+  geq = (==)++instance GEq m => GEq (WrappedMonoid m) where+  geq = geqdefault++instance GEq a => GEq (ZipList a) where+  geq = geqdefault++#if MIN_VERSION_base(4,10,0)+instance GEq CBool where+  geq = (==)++# if defined(HTYPE_BLKSIZE_T)+instance GEq CBlkSize where+  geq = (==)+# endif++# if defined(HTYPE_BLKCNT_T)+instance GEq CBlkCnt where+  geq = (==)+# endif++# if defined(HTYPE_CLOCKID_T)+instance GEq CClockId where+  geq = (==)+# endif++# if defined(HTYPE_FSBLKCNT_T)+instance GEq CFsBlkCnt where+  geq = (==)+# endif++# if defined(HTYPE_FSFILCNT_T)+instance GEq CFsFilCnt where+  geq = (==)+# endif++# if defined(HTYPE_ID_T)+instance GEq CId where+  geq = (==)+# endif++# if defined(HTYPE_KEY_T)+instance GEq CKey where+  geq = (==)+# endif++# if defined(HTYPE_TIMER_T)+instance GEq CTimer where+  geq = (==)+# endif+#endif
src/Generics/Deriving/Foldable.hs view
@@ -1,175 +1,274 @@-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
-module Generics.Deriving.Foldable (
-  -- * Foldable class
-    GFoldable(..)
-
-  -- * Default method
-  , gfoldMapdefault
-
-  -- * Derived functions
-  , gtoList
-  , gconcat
-  , gconcatMap
-  , gand
-  , gor
-  , gany
-  , gall
-  , gsum
-  , gproduct
-  , gmaximum
-  , gmaximumBy
-  , gminimum
-  , gminimumBy
-  , gelem
-  , gnotElem
-  , gfind
-  ) where
-
-import Data.Maybe
-import Data.Monoid
-import Generics.Deriving.Base
-import Generics.Deriving.Instances ()
-
---------------------------------------------------------------------------------
--- Generic fold
---------------------------------------------------------------------------------
-
-class GFoldable' t where
-  gfoldMap' :: Monoid m => (a -> m) -> t a -> m
-
-instance GFoldable' U1 where
-  gfoldMap' _ U1 = mempty
-
-instance GFoldable' Par1 where
-  gfoldMap' f (Par1 a) = f a
-
-instance GFoldable' (K1 i c) where
-  gfoldMap' _ (K1 _) = mempty
-
-instance (GFoldable f) => GFoldable' (Rec1 f) where
-  gfoldMap' f (Rec1 a) = gfoldMap f a
-
-instance (GFoldable' f) => GFoldable' (M1 i c f) where
-  gfoldMap' f (M1 a) = gfoldMap' f a
-
-instance (GFoldable' f, GFoldable' g) => GFoldable' (f :+: g) where
-  gfoldMap' f (L1 a) = gfoldMap' f a
-  gfoldMap' f (R1 a) = gfoldMap' f a
-
-instance (GFoldable' f, GFoldable' g) => GFoldable' (f :*: g) where
-  gfoldMap' f (a :*: b) = mappend (gfoldMap' f a) (gfoldMap' f b)
-
-instance (GFoldable f, GFoldable' g) => GFoldable' (f :.: g) where
-  gfoldMap' f (Comp1 x) = gfoldMap (gfoldMap' f) x
-
-
-class GFoldable t where
-  gfoldMap :: Monoid m => (a -> m) -> t a -> m
-#if __GLASGOW_HASKELL__ >= 701
-  default gfoldMap :: (Generic1 t, GFoldable' (Rep1 t), Monoid m)
-                   => (a -> m) -> t a -> m
-  gfoldMap = gfoldMapdefault
-#endif
-
-  gfold :: Monoid m => t m -> m
-  gfold = gfoldMap id
-
-  gfoldr :: (a -> b -> b) -> b -> t a -> b
-  gfoldr f z t = appEndo (gfoldMap (Endo . f) t) z
-
-  gfoldr' :: (a -> b -> b) -> b -> t a -> b
-  gfoldr' f z0 xs = gfoldl f' id xs z0
-    where f' k x z = k $! f x z
-
-  gfoldl :: (a -> b -> a) -> a -> t b -> a
-  gfoldl f z t = appEndo (getDual (gfoldMap (Dual . Endo . flip f) t)) z
-
-  gfoldl' :: (a -> b -> a) -> a -> t b -> a
-  gfoldl' f z0 xs = gfoldr f' id xs z0
-    where f' x k z = k $! f z x
-
-  gfoldr1 :: (a -> a -> a) -> t a -> a
-  gfoldr1 f xs = fromMaybe (error "gfoldr1: empty structure")
-                   (gfoldr mf Nothing xs)
-    where
-      mf x Nothing = Just x
-      mf x (Just y) = Just (f x y)
-
-  gfoldl1 :: (a -> a -> a) -> t a -> a
-  gfoldl1 f xs = fromMaybe (error "foldl1: empty structure")
-                   (gfoldl mf Nothing xs)
-    where
-      mf Nothing y = Just y
-      mf (Just x) y = Just (f x y)
-
-gfoldMapdefault :: (Generic1 t, GFoldable' (Rep1 t), Monoid m)
-                => (a -> m) -> t a -> m
-gfoldMapdefault f x = gfoldMap' f (from1 x)
-
--- Base types instances
-instance GFoldable Maybe where
-  gfoldMap = gfoldMapdefault
-
-instance GFoldable [] where
-  gfoldMap = gfoldMapdefault
-
-gtoList :: GFoldable t => t a -> [a]
-gtoList = gfoldr (:) []
-
-gconcat :: GFoldable t => t [a] -> [a]
-gconcat = gfold
-
-gconcatMap :: GFoldable t => (a -> [b]) -> t a -> [b]
-gconcatMap = gfoldMap
-
-gand :: GFoldable t => t Bool -> Bool
-gand = getAll . gfoldMap All
-
-gor :: GFoldable t => t Bool -> Bool
-gor = getAny . gfoldMap Any
-
-gany :: GFoldable t => (a -> Bool) -> t a -> Bool
-gany p = getAny . gfoldMap (Any . p)
-
-gall :: GFoldable t => (a -> Bool) -> t a -> Bool
-gall p = getAll . gfoldMap (All . p)
-
-gsum :: (GFoldable t, Num a) => t a -> a
-gsum = getSum . gfoldMap Sum
-
-gproduct :: (GFoldable t, Num a) => t a -> a
-gproduct = getProduct . gfoldMap Product
-
-gmaximum :: (GFoldable t, Ord a) => t a -> a
-gmaximum = gfoldr1 max
-
-gmaximumBy :: GFoldable t => (a -> a -> Ordering) -> t a -> a
-gmaximumBy cmp = gfoldr1 max'
-  where max' x y = case cmp x y of
-                        GT -> x
-                        _  -> y
-
-gminimum :: (GFoldable t, Ord a) => t a -> a
-gminimum = gfoldr1 min
-
-gminimumBy :: GFoldable t => (a -> a -> Ordering) -> t a -> a
-gminimumBy cmp = gfoldr1 min'
-  where min' x y = case cmp x y of
-                        GT -> y
-                        _  -> x
-
-gelem :: (GFoldable t, Eq a) => a -> t a -> Bool
-gelem = gany . (==)
-
-gnotElem :: (GFoldable t, Eq a) => a -> t a -> Bool
-gnotElem x = not . gelem x
-
-gfind :: GFoldable t => (a -> Bool) -> t a -> Maybe a
-gfind p = listToMaybe . gconcatMap (\ x -> if p x then [x] else [])
-
+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Generics.Deriving.Foldable (+  -- * Generic Foldable class+    GFoldable(..)++  -- * Default method+  , gfoldMapdefault++  -- * Derived functions+  , gtoList+  , gconcat+  , gconcatMap+  , gand+  , gor+  , gany+  , gall+  , gsum+  , gproduct+  , gmaximum+  , gmaximumBy+  , gminimum+  , gminimumBy+  , gelem+  , gnotElem+  , gfind++  -- * Internal Foldable class+  , GFoldable'(..)+  ) where++import           Control.Applicative (Const, ZipList)++import           Data.Complex (Complex)+import           Data.Functor.Identity (Identity)+import qualified Data.Functor.Product as Functor (Product)+import qualified Data.Functor.Sum as Functor (Sum)+import           Data.List.NonEmpty (NonEmpty)+import           Data.Maybe+import qualified Data.Monoid as Monoid (First, Last, Product(..), Sum(..))+import           Data.Monoid (All(..), Any(..), Dual(..), Endo(..))+import           Data.Ord (Down)+import           Data.Proxy (Proxy)+import qualified Data.Semigroup as Semigroup (First, Last)+import           Data.Semigroup (Arg, Max, Min, WrappedMonoid)++import           Generics.Deriving.Base++--------------------------------------------------------------------------------+-- Generic fold+--------------------------------------------------------------------------------++class GFoldable' t where+  gfoldMap' :: Monoid m => (a -> m) -> t a -> m++instance GFoldable' V1 where+  gfoldMap' _ _ = mempty++instance GFoldable' U1 where+  gfoldMap' _ U1 = mempty++instance GFoldable' Par1 where+  gfoldMap' f (Par1 a) = f a++instance GFoldable' (K1 i c) where+  gfoldMap' _ (K1 _) = mempty++instance (GFoldable f) => GFoldable' (Rec1 f) where+  gfoldMap' f (Rec1 a) = gfoldMap f a++instance (GFoldable' f) => GFoldable' (M1 i c f) where+  gfoldMap' f (M1 a) = gfoldMap' f a++instance (GFoldable' f, GFoldable' g) => GFoldable' (f :+: g) where+  gfoldMap' f (L1 a) = gfoldMap' f a+  gfoldMap' f (R1 a) = gfoldMap' f a++instance (GFoldable' f, GFoldable' g) => GFoldable' (f :*: g) where+  gfoldMap' f (a :*: b) = mappend (gfoldMap' f a) (gfoldMap' f b)++instance (GFoldable f, GFoldable' g) => GFoldable' (f :.: g) where+  gfoldMap' f (Comp1 x) = gfoldMap (gfoldMap' f) x++instance GFoldable' UAddr where+  gfoldMap' _ (UAddr _) = mempty++instance GFoldable' UChar where+  gfoldMap' _ (UChar _) = mempty++instance GFoldable' UDouble where+  gfoldMap' _ (UDouble _) = mempty++instance GFoldable' UFloat where+  gfoldMap' _ (UFloat _) = mempty++instance GFoldable' UInt where+  gfoldMap' _ (UInt _) = mempty++instance GFoldable' UWord where+  gfoldMap' _ (UWord _) = mempty++class GFoldable t where+  gfoldMap :: Monoid m => (a -> m) -> t a -> m+  default gfoldMap :: (Generic1 t, GFoldable' (Rep1 t), Monoid m)+                   => (a -> m) -> t a -> m+  gfoldMap = gfoldMapdefault++  gfold :: Monoid m => t m -> m+  gfold = gfoldMap id++  gfoldr :: (a -> b -> b) -> b -> t a -> b+  gfoldr f z t = appEndo (gfoldMap (Endo . f) t) z++  gfoldr' :: (a -> b -> b) -> b -> t a -> b+  gfoldr' f z0 xs = gfoldl f' id xs z0+    where f' k x z = k $! f x z++  gfoldl :: (a -> b -> a) -> a -> t b -> a+  gfoldl f z t = appEndo (getDual (gfoldMap (Dual . Endo . flip f) t)) z++  gfoldl' :: (a -> b -> a) -> a -> t b -> a+  gfoldl' f z0 xs = gfoldr f' id xs z0+    where f' x k z = k $! f z x++  gfoldr1 :: (a -> a -> a) -> t a -> a+  gfoldr1 f xs = fromMaybe (error "gfoldr1: empty structure")+                   (gfoldr mf Nothing xs)+    where+      mf x Nothing = Just x+      mf x (Just y) = Just (f x y)++  gfoldl1 :: (a -> a -> a) -> t a -> a+  gfoldl1 f xs = fromMaybe (error "foldl1: empty structure")+                   (gfoldl mf Nothing xs)+    where+      mf Nothing y = Just y+      mf (Just x) y = Just (f x y)++gfoldMapdefault :: (Generic1 t, GFoldable' (Rep1 t), Monoid m)+                => (a -> m) -> t a -> m+gfoldMapdefault f x = gfoldMap' f (from1 x)++-- Base types instances+instance GFoldable ((,) a) where+  gfoldMap = gfoldMapdefault++instance GFoldable [] where+  gfoldMap = gfoldMapdefault++instance GFoldable (Arg a) where+  gfoldMap = gfoldMapdefault++instance GFoldable Complex where+  gfoldMap = gfoldMapdefault++instance GFoldable (Const m) where+  gfoldMap = gfoldMapdefault++instance GFoldable Down where+  gfoldMap = gfoldMapdefault++instance GFoldable Dual where+  gfoldMap = gfoldMapdefault++instance GFoldable (Either a) where+  gfoldMap = gfoldMapdefault++instance GFoldable Monoid.First where+  gfoldMap = gfoldMapdefault++instance GFoldable (Semigroup.First) where+  gfoldMap = gfoldMapdefault++instance GFoldable Identity where+  gfoldMap = gfoldMapdefault++instance GFoldable Monoid.Last where+  gfoldMap = gfoldMapdefault++instance GFoldable Semigroup.Last where+  gfoldMap = gfoldMapdefault++instance GFoldable Max where+  gfoldMap = gfoldMapdefault++instance GFoldable Maybe where+  gfoldMap = gfoldMapdefault++instance GFoldable Min where+  gfoldMap = gfoldMapdefault++instance GFoldable NonEmpty where+  gfoldMap = gfoldMapdefault++instance GFoldable Monoid.Product where+  gfoldMap = gfoldMapdefault++instance (GFoldable f, GFoldable g) => GFoldable (Functor.Product f g) where+  gfoldMap = gfoldMapdefault++instance GFoldable Proxy where+  gfoldMap = gfoldMapdefault++instance GFoldable Monoid.Sum where+  gfoldMap = gfoldMapdefault++instance (GFoldable f, GFoldable g) => GFoldable (Functor.Sum f g) where+  gfoldMap = gfoldMapdefault++instance GFoldable WrappedMonoid where+  gfoldMap = gfoldMapdefault++instance GFoldable ZipList where+  gfoldMap = gfoldMapdefault++gtoList :: GFoldable t => t a -> [a]+gtoList = gfoldr (:) []++gconcat :: GFoldable t => t [a] -> [a]+gconcat = gfold++gconcatMap :: GFoldable t => (a -> [b]) -> t a -> [b]+gconcatMap = gfoldMap++gand :: GFoldable t => t Bool -> Bool+gand = getAll . gfoldMap All++gor :: GFoldable t => t Bool -> Bool+gor = getAny . gfoldMap Any++gany :: GFoldable t => (a -> Bool) -> t a -> Bool+gany p = getAny . gfoldMap (Any . p)++gall :: GFoldable t => (a -> Bool) -> t a -> Bool+gall p = getAll . gfoldMap (All . p)++gsum :: (GFoldable t, Num a) => t a -> a+gsum = Monoid.getSum . gfoldMap Monoid.Sum++gproduct :: (GFoldable t, Num a) => t a -> a+gproduct = Monoid.getProduct . gfoldMap Monoid.Product++gmaximum :: (GFoldable t, Ord a) => t a -> a+gmaximum = gfoldr1 max++gmaximumBy :: GFoldable t => (a -> a -> Ordering) -> t a -> a+gmaximumBy cmp = gfoldr1 max'+  where max' x y = case cmp x y of+                        GT -> x+                        _  -> y++gminimum :: (GFoldable t, Ord a) => t a -> a+gminimum = gfoldr1 min++gminimumBy :: GFoldable t => (a -> a -> Ordering) -> t a -> a+gminimumBy cmp = gfoldr1 min'+  where min' x y = case cmp x y of+                        GT -> y+                        _  -> x++gelem :: (GFoldable t, Eq a) => a -> t a -> Bool+gelem = gany . (==)++gnotElem :: (GFoldable t, Eq a) => a -> t a -> Bool+gnotElem x = not . gelem x++gfind :: GFoldable t => (a -> Bool) -> t a -> Maybe a+gfind p = listToMaybe . gconcatMap (\ x -> if p x then [x] else [])
src/Generics/Deriving/Functor.hs view
@@ -1,70 +1,182 @@-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
-module Generics.Deriving.Functor (
-  -- * GFunctor class
-    GFunctor(..)
-
-  -- * Default method
-  , gmapdefault
-
-  ) where
-
-import Generics.Deriving.Base
-import Generics.Deriving.Instances ()
-
---------------------------------------------------------------------------------
--- Generic fmap
---------------------------------------------------------------------------------
-
-class GFunctor' f where
-  gmap' :: (a -> b) -> f a -> f b
-
-instance GFunctor' U1 where
-  gmap' _ U1 = U1
-
-instance GFunctor' Par1 where
-  gmap' f (Par1 a) = Par1 (f a)
-
-instance GFunctor' (K1 i c) where
-  gmap' _ (K1 a) = K1 a
-
-instance (GFunctor f) => GFunctor' (Rec1 f) where
-  gmap' f (Rec1 a) = Rec1 (gmap f a)
-
-instance (GFunctor' f) => GFunctor' (M1 i c f) where
-  gmap' f (M1 a) = M1 (gmap' f a)
-
-instance (GFunctor' f, GFunctor' g) => GFunctor' (f :+: g) where
-  gmap' f (L1 a) = L1 (gmap' f a)
-  gmap' f (R1 a) = R1 (gmap' f a)
-
-instance (GFunctor' f, GFunctor' g) => GFunctor' (f :*: g) where
-  gmap' f (a :*: b) = gmap' f a :*: gmap' f b
-
-instance (GFunctor f, GFunctor' g) => GFunctor' (f :.: g) where
-  gmap' f (Comp1 x) = Comp1 (gmap (gmap' f) x)
-
-
-class GFunctor f where
-  gmap :: (a -> b) -> f a -> f b
-#if __GLASGOW_HASKELL__ >= 701
-  default gmap :: (Generic1 f, GFunctor' (Rep1 f))
-               => (a -> b) -> f a -> f b
-  gmap = gmapdefault
-#endif
-
-gmapdefault :: (Generic1 f, GFunctor' (Rep1 f))
-            => (a -> b) -> f a -> f b
-gmapdefault f = to1 . gmap' f . from1
-
--- Base types instances
-instance GFunctor Maybe where
-  gmap = gmapdefault
-
-instance GFunctor [] where
-  gmap = gmapdefault
+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Generics.Deriving.Functor (+  -- * Generic Functor class+    GFunctor(..)++  -- * Default method+  , gmapdefault++  -- * Internal Functor class+  , GFunctor'(..)++  ) where++import           Control.Applicative (Const, ZipList)++import           Data.Complex (Complex)+import           Data.Functor.Identity (Identity)+import qualified Data.Functor.Product as Functor (Product)+import qualified Data.Functor.Sum as Functor (Sum)+import           Data.List.NonEmpty (NonEmpty)+import qualified Data.Monoid as Monoid (First, Last, Product, Sum)+import           Data.Monoid (Alt, Dual)+import           Data.Ord (Down)+import           Data.Proxy (Proxy)+import qualified Data.Semigroup as Semigroup (First, Last)+import           Data.Semigroup (Arg, Max, Min, WrappedMonoid)++import           Generics.Deriving.Base++--------------------------------------------------------------------------------+-- Generic fmap+--------------------------------------------------------------------------------++class GFunctor' f where+  gmap' :: (a -> b) -> f a -> f b++instance GFunctor' V1 where+  gmap' _ x = case x of {}++instance GFunctor' U1 where+  gmap' _ U1 = U1++instance GFunctor' Par1 where+  gmap' f (Par1 a) = Par1 (f a)++instance GFunctor' (K1 i c) where+  gmap' _ (K1 a) = K1 a++instance (GFunctor f) => GFunctor' (Rec1 f) where+  gmap' f (Rec1 a) = Rec1 (gmap f a)++instance (GFunctor' f) => GFunctor' (M1 i c f) where+  gmap' f (M1 a) = M1 (gmap' f a)++instance (GFunctor' f, GFunctor' g) => GFunctor' (f :+: g) where+  gmap' f (L1 a) = L1 (gmap' f a)+  gmap' f (R1 a) = R1 (gmap' f a)++instance (GFunctor' f, GFunctor' g) => GFunctor' (f :*: g) where+  gmap' f (a :*: b) = gmap' f a :*: gmap' f b++instance (GFunctor f, GFunctor' g) => GFunctor' (f :.: g) where+  gmap' f (Comp1 x) = Comp1 (gmap (gmap' f) x)++instance GFunctor' UAddr where+  gmap' _ (UAddr a) = UAddr a++instance GFunctor' UChar where+  gmap' _ (UChar c) = UChar c++instance GFunctor' UDouble where+  gmap' _ (UDouble d) = UDouble d++instance GFunctor' UFloat where+  gmap' _ (UFloat f) = UFloat f++instance GFunctor' UInt where+  gmap' _ (UInt i) = UInt i++instance GFunctor' UWord where+  gmap' _ (UWord w) = UWord w++class GFunctor f where+  gmap :: (a -> b) -> f a -> f b+  default gmap :: (Generic1 f, GFunctor' (Rep1 f))+               => (a -> b) -> f a -> f b+  gmap = gmapdefault++gmapdefault :: (Generic1 f, GFunctor' (Rep1 f))+            => (a -> b) -> f a -> f b+gmapdefault f = to1 . gmap' f . from1++-- Base types instances+instance GFunctor ((->) r) where+  gmap = fmap++instance GFunctor ((,) a) where+  gmap = gmapdefault++instance GFunctor [] where+  gmap = gmapdefault++instance GFunctor f => GFunctor (Alt f) where+  gmap = gmapdefault++instance GFunctor (Arg a) where+  gmap = gmapdefault++instance GFunctor Complex where+  gmap = gmapdefault++instance GFunctor (Const m) where+  gmap = gmapdefault++instance GFunctor Down where+  gmap = gmapdefault++instance GFunctor Dual where+  gmap = gmapdefault++instance GFunctor (Either a) where+  gmap = gmapdefault++instance GFunctor Monoid.First where+  gmap = gmapdefault++instance GFunctor (Semigroup.First) where+  gmap = gmapdefault++instance GFunctor Identity where+  gmap = gmapdefault++instance GFunctor IO where+  gmap = fmap++instance GFunctor Monoid.Last where+  gmap = gmapdefault++instance GFunctor Semigroup.Last where+  gmap = gmapdefault++instance GFunctor Max where+  gmap = gmapdefault++instance GFunctor Maybe where+  gmap = gmapdefault++instance GFunctor Min where+  gmap = gmapdefault++instance GFunctor NonEmpty where+  gmap = gmapdefault++instance GFunctor Monoid.Product where+  gmap = gmapdefault++instance (GFunctor f, GFunctor g) => GFunctor (Functor.Product f g) where+  gmap = gmapdefault++instance GFunctor Proxy where+  gmap = gmapdefault++instance GFunctor Monoid.Sum where+  gmap = gmapdefault++instance (GFunctor f, GFunctor g) => GFunctor (Functor.Sum f g) where+  gmap = gmapdefault++instance GFunctor WrappedMonoid where+  gmap = gmapdefault++instance GFunctor ZipList where+  gmap = gmapdefault
src/Generics/Deriving/Instances.hs view
@@ -1,134 +1,106 @@-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-
-module Generics.Deriving.Instances (
--- Only instances from Generics.Deriving.Base
--- and the Generic1 instances
-#if __GLASGOW_HASKELL__ < 705
-    Rep1Maybe, Rep1List
-#endif
-#if __GLASGOW_HASKELL__ < 701
-  -- * Representations for base types
-  , Rep0Char, Rep0Int, Rep0Float
-  , Rep0Maybe, Rep0List
-#endif
-  ) where
-
-#if __GLASGOW_HASKELL__ < 705
-import Generics.Deriving.Base
-#endif
-
-#if __GLASGOW_HASKELL__ < 701
---------------------------------------------------------------------------------
--- Representation for base types
---------------------------------------------------------------------------------
-
--- Representation types
-{-
-type Rep1Par1 = Par1
-instance Generic1 Par1 Rep1Par1 where
-  from1 = id
-  to1 = id
-
-type Rep1Rec1 f = Rec1 f
-instance Generic1 (Rec1 f) (Rep1Rec1 f) where
-  from1 = id
-  to1 = id
--}
--- Kind *
-
-type Rep0Char = Rec0 Char
-instance Generic Char where
-  type Rep Char = Rep0Char
-  from = K1
-  to = unK1
-
-type Rep0Int = Rec0 Int
-instance Generic Int where
-  type Rep Int = Rep0Int
-  from = K1
-  to = unK1
-
-type Rep0Float = Rec0 Float
-instance Generic Float where
-  type Rep Float = Rep0Float
-  from = K1
-  to = unK1
-
--- etc...
-
--- Kind * -> *
-
-type Rep0Maybe a = D1 Maybe_ (C1 Nothing_ U1 :+: C1 Just_ (Par0 a))
-instance Generic (Maybe a) where
-  type Rep (Maybe a) = Rep0Maybe a
-  from Nothing  = M1 (L1 (M1 U1))
-  from (Just x) = M1 (R1 (M1 (K1 x)))
-  to (M1 (L1 (M1 U1)))     = Nothing
-  to (M1 (R1 (M1 (K1 x)))) = Just x
-
-type Rep0List a = D1 List__ ((C1 Nil__ U1) :+: (C1 Cons__ (Par0 a :*: Rec0 [a])))
-instance Generic [a] where
-  type Rep [a] = Rep0List a
-  from []    = M1 (L1 (M1 U1))
-  from (h:t) = M1 (R1 (M1 (K1 h :*: K1 t)))
-  to (M1 (L1 (M1 U1)))              = []
-  to (M1 (R1 (M1 (K1 h :*: K1 t)))) = h : t
-#endif
-
-#if __GLASGOW_HASKELL__ < 705
--- GHC 7.2 and 7.4 still need these instances; 7.6 doesn't
-
-data Maybe_
-data Nothing_
-data Just_
-
-instance Datatype Maybe_ where
-  datatypeName _ = "Maybe"
-  moduleName   _ = "Representation"
-
-instance Constructor Nothing_ where
-  conName _ = "Nothing"
-
-instance Constructor Just_ where
-  conName _ = "Just"
-
-
-type Rep1Maybe = D1 Maybe_ (C1 Nothing_ U1 :+: C1 Just_ Par1)
-instance Generic1 Maybe where
-  type Rep1 Maybe = Rep1Maybe
-  from1 Nothing  = M1 (L1 (M1 U1))
-  from1 (Just x) = M1 (R1 (M1 (Par1 x)))
-  to1 (M1 (L1 (M1 U1)))       = Nothing
-  to1 (M1 (R1 (M1 (Par1 x)))) = Just x
-
-
-data List__
-data Nil__
-data Cons__
-
-instance Datatype List__ where
-  datatypeName _ = "[]"
-  moduleName   _ = "Data.List"
-
-instance Constructor Nil__  where conName _ = "[]"
-instance Constructor Cons__ where
-  conName   _ = ":"
-  conFixity _ = Infix RightAssociative 5
-
-
-type Rep1List = D1 List__ ((C1 Nil__ U1) :+: (C1 Cons__ (Par1 :*: Rec1 [])))
-instance Generic1 [] where
-  type Rep1 [] = Rep1List
-  from1 []    = M1 (L1 (M1 U1))
-  from1 (h:t) = M1 (R1 (M1 (Par1 h :*: Rec1 t)))
-  to1 (M1 (L1 (M1 U1)))                  = []
-  to1 (M1 (R1 (M1 (Par1 h :*: Rec1 t)))) = h : t
-
--- etc...
-
-#endif
+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Generics.Deriving.Instances (+-- Only instances from GHC.Generics+-- and the Generic1 instances+#if !(MIN_VERSION_base(4,16,0))+    Rep0Tuple8+  , Rep0Tuple9+  , Rep0Tuple10+  , Rep0Tuple11+  , Rep0Tuple12+  , Rep0Tuple13+  , Rep0Tuple14+  , Rep0Tuple15+  , Rep1Tuple8+  , Rep1Tuple9+  , Rep1Tuple10+  , Rep1Tuple11+  , Rep1Tuple12+  , Rep1Tuple13+  , Rep1Tuple14+  , Rep1Tuple15+#endif+#if !(MIN_VERSION_base(4,14,0))+  , Rep0Kleisli+  , Rep1Kleisli+#endif+#if !(MIN_VERSION_base(4,12,0))+  , Rep0Down+  , Rep1Down+#endif+  ) where++#if !(MIN_VERSION_base(4,12,0))+import Data.Ord (Down(..))+#endif++#if !(MIN_VERSION_base(4,14,0))+import Control.Arrow (Kleisli(..))+#endif++#if !(MIN_VERSION_base(4,16,0))+import GHC.Generics+#endif++#if !(MIN_VERSION_base(4,16,0))+type Rep0Tuple8  a b c d e f g h               = Rep (a, b, c, d, e, f, g, h)+type Rep0Tuple9  a b c d e f g h i             = Rep (a, b, c, d, e, f, g, h, i)+type Rep0Tuple10 a b c d e f g h i j           = Rep (a, b, c, d, e, f, g, h, i, j)+type Rep0Tuple11 a b c d e f g h i j k         = Rep (a, b, c, d, e, f, g, h, i, j, k)+type Rep0Tuple12 a b c d e f g h i j k l       = Rep (a, b, c, d, e, f, g, h, i, j, k, l)+type Rep0Tuple13 a b c d e f g h i j k l m     = Rep (a, b, c, d, e, f, g, h, i, j, k, l, m)+type Rep0Tuple14 a b c d e f g h i j k l m n   = Rep (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+type Rep0Tuple15 a b c d e f g h i j k l m n o = Rep (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+type Rep1Tuple8  a b c d e f g               = Rep1 ((,,,,,,,) a b c d e f g)+type Rep1Tuple9  a b c d e f g h             = Rep1 ((,,,,,,,,) a b c d e f g h)+type Rep1Tuple10 a b c d e f g h i           = Rep1 ((,,,,,,,,,) a b c d e f g h i)+type Rep1Tuple11 a b c d e f g h i j         = Rep1 ((,,,,,,,,,,) a b c d e f g h i j)+type Rep1Tuple12 a b c d e f g h i j k       = Rep1 ((,,,,,,,,,,,) a b c d e f g h i j k)+type Rep1Tuple13 a b c d e f g h i j k l     = Rep1 ((,,,,,,,,,,,,) a b c d e f g h i j k l)+type Rep1Tuple14 a b c d e f g h i j k l m   = Rep1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m)+type Rep1Tuple15 a b c d e f g h i j k l m n = Rep1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n)+deriving instance Generic (a, b, c, d, e, f, g, h)+deriving instance Generic (a, b, c, d, e, f, g, h, i)+deriving instance Generic (a, b, c, d, e, f, g, h, i, j)+deriving instance Generic (a, b, c, d, e, f, g, h, i, j, k)+deriving instance Generic (a, b, c, d, e, f, g, h, i, j, k, l)+deriving instance Generic (a, b, c, d, e, f, g, h, i, j, k, l, m)+deriving instance Generic (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+deriving instance Generic (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+deriving instance Generic1 ((,,,,,,,) a b c d e f g)+deriving instance Generic1 ((,,,,,,,,) a b c d e f g h)+deriving instance Generic1 ((,,,,,,,,,) a b c d e f g h i)+deriving instance Generic1 ((,,,,,,,,,,) a b c d e f g h i j)+deriving instance Generic1 ((,,,,,,,,,,,) a b c d e f g h i j k)+deriving instance Generic1 ((,,,,,,,,,,,,) a b c d e f g h i j k l)+deriving instance Generic1 ((,,,,,,,,,,,,,) a b c d e f g h i j k l m)+deriving instance Generic1 ((,,,,,,,,,,,,,,) a b c d e f g h i j k l m n)+#endif++#if !(MIN_VERSION_base(4,14,0))+type Rep0Kleisli m a b = Rep  (Kleisli m a b)+type Rep1Kleisli m a   = Rep1 (Kleisli m a)+deriving instance Generic  (Kleisli m a b)+deriving instance Generic1 (Kleisli m a)+#endif++#if !(MIN_VERSION_base(4,12,0))+type Rep0Down a = Rep (Down a)+type Rep1Down   = Rep1 Down+deriving instance Generic (Down a)+deriving instance Generic1 Down+#endif
src/Generics/Deriving/Monoid.hs view
@@ -1,217 +1,17 @@-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE FlexibleContexts #-}
-
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
--- | This module provides two main features:
---
---     1. 'GMonoid', a generic version of the 'Monoid' type class, including instances
---     of the types from "Data.Monoid"
---
---     2. Default generic definitions for the 'Monoid' methods 'mempty' and 'mappend'
---
--- The generic defaults only work for types without alternatives (i.e. they have
--- only one constructor). We cannot in general know how to deal with different
--- constructors.
-
-module Generics.Deriving.Monoid (
-
-  -- * GMonoid type class
-  GMonoid(..),
-
-  -- * Default definitions
-  -- ** GMonoid
-  gmemptydefault,
-  gmappenddefault,
-
-  -- ** Monoid
-  -- | These functions can be used in a 'Monoid' instance. For example:
-  --
-  -- @
-  -- -- LANGUAGE DeriveGeneric
-  --
-  -- import Generics.Deriving.Base (Generic)
-  -- import Generics.Deriving.Monoid
-  --
-  -- data T a = C a (Maybe a) deriving Generic
-  --
-  -- instance Monoid a => Monoid (T a) where
-  --   mempty  = memptydefault
-  --   mappend = mappenddefault
-  -- @
-  memptydefault,
-  mappenddefault,
-
-  -- * The Monoid module
-  -- | This is exported for convenient access to the various wrapper types.
-  module Data.Monoid,
-
-  ) where
-
---------------------------------------------------------------------------------
-
-import Generics.Deriving.Base
-import Generics.Deriving.Instances ()
-import Data.Monoid
-
---------------------------------------------------------------------------------
-
-class GMonoid' f where
-  gmempty'  :: f x
-  gmappend' :: f x -> f x -> f x
-
-instance GMonoid' U1 where
-  gmempty' = U1
-  gmappend' U1 U1 = U1
-
-instance GMonoid a => GMonoid' (K1 i a) where
-  gmempty' = K1 gmempty
-  gmappend' (K1 x) (K1 y) = K1 (x `gmappend` y)
-
-instance GMonoid' f => GMonoid' (M1 i c f) where
-  gmempty' = M1 gmempty'
-  gmappend' (M1 x) (M1 y) = M1 (x `gmappend'` y)
-
-instance (GMonoid' f, GMonoid' h) => GMonoid' (f :*: h) where
-  gmempty' = gmempty' :*: gmempty'
-  gmappend' (x1 :*: y1) (x2 :*: y2) = gmappend' x1 x2 :*: gmappend' y1 y2
-
---------------------------------------------------------------------------------
-
-gmemptydefault :: (Generic a, GMonoid' (Rep a)) => a
-gmemptydefault = to gmempty'
-
-gmappenddefault :: (Generic a, GMonoid' (Rep a)) => a -> a -> a
-gmappenddefault x y = to (gmappend' (from x) (from y))
-
---------------------------------------------------------------------------------
-
-class Monoid' f where
-  mempty'  :: f x
-  mappend' :: f x -> f x -> f x
-
-instance Monoid' U1 where
-  mempty' = U1
-  mappend' U1 U1 = U1
-
-instance Monoid a => Monoid' (K1 i a) where
-  mempty' = K1 mempty
-  mappend' (K1 x) (K1 y) = K1 (x `mappend` y)
-
-instance Monoid' f => Monoid' (M1 i c f) where
-  mempty' = M1 mempty'
-  mappend' (M1 x) (M1 y) = M1 (x `mappend'` y)
-
-instance (Monoid' f, Monoid' h) => Monoid' (f :*: h) where
-  mempty' = mempty' :*: mempty'
-  mappend' (x1 :*: y1) (x2 :*: y2) = mappend' x1 x2 :*: mappend' y1 y2
-
---------------------------------------------------------------------------------
-
-memptydefault :: (Generic a, Monoid' (Rep a)) => a
-memptydefault = to mempty'
-
-mappenddefault :: (Generic a, Monoid' (Rep a)) => a -> a -> a
-mappenddefault x y = to (mappend' (from x) (from y))
-
---------------------------------------------------------------------------------
-
-class GMonoid a where
-
-  -- | Generic 'mempty'
-  gmempty  :: a
-
-  -- | Generic 'mappend'
-  gmappend :: a -> a -> a
-
-  -- | Generic 'mconcat'
-  gmconcat :: [a] -> a
-  gmconcat = foldr gmappend gmempty
-
-#if __GLASGOW_HASKELL__ >= 701
-  default gmempty :: (Generic a, GMonoid' (Rep a)) => a
-  gmempty = to gmempty'
-
-  default gmappend :: (Generic a, GMonoid' (Rep a)) => a -> a -> a
-  gmappend x y = to (gmappend' (from x) (from y))
-#endif
-
---------------------------------------------------------------------------------
-
--- Instances that reuse Monoid
-instance GMonoid Ordering where
-  gmempty = mempty
-  gmappend = mappend
-instance GMonoid () where
-  gmempty = mempty
-  gmappend = mappend
-instance GMonoid Any where
-  gmempty = mempty
-  gmappend = mappend
-instance GMonoid All where
-  gmempty = mempty
-  gmappend = mappend
-instance GMonoid (First a) where
-  gmempty = mempty
-  gmappend = mappend
-instance GMonoid (Last a) where
-  gmempty = mempty
-  gmappend = mappend
-instance Num a => GMonoid (Sum a) where
-  gmempty = mempty
-  gmappend = mappend
-instance Num a => GMonoid (Product a) where
-  gmempty = mempty
-  gmappend = mappend
-instance GMonoid [a] where
-  gmempty  = mempty
-  gmappend = mappend
-instance GMonoid (Endo a) where
-  gmempty = mempty
-  gmappend = mappend
-
--- Handwritten instances
-instance GMonoid a => GMonoid (Dual a) where
-  gmempty = Dual gmempty
-  gmappend (Dual x) (Dual y) = Dual (gmappend y x)
-instance GMonoid a => GMonoid (Maybe a) where
-  gmempty = Nothing
-  gmappend Nothing  x        = x
-  gmappend x        Nothing  = x
-  gmappend (Just x) (Just y) = Just (gmappend x y)
-instance GMonoid b => GMonoid (a -> b) where
-  gmempty _ = gmempty
-  gmappend f g x = gmappend (f x) (g x)
-
--- Tuple instances
-instance (GMonoid a,GMonoid b) => GMonoid (a,b) where
-  gmempty = (gmempty,gmempty)
-  gmappend (a1,b1) (a2,b2) =
-    (gmappend a1 a2,gmappend b1 b2)
-instance (GMonoid a,GMonoid b,GMonoid c) => GMonoid (a,b,c) where
-  gmempty = (gmempty,gmempty,gmempty)
-  gmappend (a1,b1,c1) (a2,b2,c2) =
-    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2)
-instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d) => GMonoid (a,b,c,d) where
-  gmempty = (gmempty,gmempty,gmempty,gmempty)
-  gmappend (a1,b1,c1,d1) (a2,b2,c2,d2) =
-    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2)
-instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e) => GMonoid (a,b,c,d,e) where
-  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty)
-  gmappend (a1,b1,c1,d1,e1) (a2,b2,c2,d2,e2) =
-    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2)
-instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e,GMonoid f) => GMonoid (a,b,c,d,e,f) where
-  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty,gmempty)
-  gmappend (a1,b1,c1,d1,e1,f1) (a2,b2,c2,d2,e2,f2) =
-    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2,gmappend f1 f2)
-instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e,GMonoid f,GMonoid g) => GMonoid (a,b,c,d,e,f,g) where
-  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty,gmempty,gmempty)
-  gmappend (a1,b1,c1,d1,e1,f1,g1) (a2,b2,c2,d2,e2,f2,g2) =
-    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2,gmappend f1 f2,gmappend g1 g2)
-instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e,GMonoid f,GMonoid g,GMonoid h) => GMonoid (a,b,c,d,e,f,g,h) where
-  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty,gmempty,gmempty,gmempty)
-  gmappend (a1,b1,c1,d1,e1,f1,g1,h1) (a2,b2,c2,d2,e2,f2,g2,h2) =
-    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2,gmappend f1 f2,gmappend g1 g2,gmappend h1 h2)
-
+{-# LANGUAGE Safe #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module Generics.Deriving.Monoid (module Generics.Deriving.Monoid.Internal) where++import Data.Semigroup (WrappedMonoid)++import Generics.Deriving.Monoid.Internal+import Generics.Deriving.Semigroup (GSemigroup(..))++instance GSemigroup a => GMonoid (Maybe a) where+  gmempty = Nothing+  gmappend = gsappend++instance GMonoid m => GMonoid (WrappedMonoid m) where+  gmempty  = gmemptydefault+  gmappend = gmappenddefault
+ src/Generics/Deriving/Monoid/Internal.hs view
@@ -0,0 +1,239 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeOperators #-}++module Generics.Deriving.Monoid.Internal (++  -- * Introduction+  {- | This module provides two main features:++      1. 'GMonoid', a generic version of the 'Monoid' type class, including instances+      of the types from "Data.Monoid"++      2. Default generic definitions for the 'Monoid' methods 'mempty' and 'mappend'++  The generic defaults only work for types without alternatives (i.e. they have+  only one constructor). We cannot in general know how to deal with different+  constructors.+  -}++  -- * GMonoid type class+  GMonoid(..),++  -- * Default definitions+  -- ** GMonoid+  gmemptydefault,+  gmappenddefault,++  -- * Internal auxiliary class for GMonoid+  GMonoid'(..),++  -- ** Monoid+  {- | These functions can be used in a 'Monoid' instance. For example:++  @+  -- LANGUAGE DeriveGeneric++  import Generics.Deriving.Base (Generic)+  import Generics.Deriving.Monoid++  data T a = C a (Maybe a) deriving Generic++  instance Monoid a => Monoid (T a) where+    mempty  = memptydefault+    mappend = mappenddefault+  @+  -}+  memptydefault,+  mappenddefault,++  -- * Internal auxiliary class for Monoid+  Monoid'(..),++  -- * The Monoid module+  -- | This is exported for convenient access to the various wrapper types.+  module Data.Monoid,++  ) where++--------------------------------------------------------------------------------++import Control.Applicative+import Data.Functor.Identity (Identity)+import Data.Monoid+import Data.Ord (Down)+import Data.Proxy (Proxy)+import Generics.Deriving.Base+import Generics.Deriving.Semigroup.Internal++--------------------------------------------------------------------------------++class GSemigroup' f => GMonoid' f where+  gmempty'  :: f x+  gmappend' :: f x -> f x -> f x++instance GMonoid' U1 where+  gmempty' = U1+  gmappend' U1 U1 = U1++instance GMonoid a => GMonoid' (K1 i a) where+  gmempty' = K1 gmempty+  gmappend' (K1 x) (K1 y) = K1 (x `gmappend` y)++instance GMonoid' f => GMonoid' (M1 i c f) where+  gmempty' = M1 gmempty'+  gmappend' (M1 x) (M1 y) = M1 (x `gmappend'` y)++instance (GMonoid' f, GMonoid' h) => GMonoid' (f :*: h) where+  gmempty' = gmempty' :*: gmempty'+  gmappend' (x1 :*: y1) (x2 :*: y2) = gmappend' x1 x2 :*: gmappend' y1 y2++--------------------------------------------------------------------------------++gmemptydefault :: (Generic a, GMonoid' (Rep a)) => a+gmemptydefault = to gmempty'++gmappenddefault :: (Generic a, GMonoid' (Rep a)) => a -> a -> a+gmappenddefault x y = to (gmappend' (from x) (from y))++--------------------------------------------------------------------------------++class Monoid' f where+  mempty'  :: f x+  mappend' :: f x -> f x -> f x++instance Monoid' U1 where+  mempty' = U1+  mappend' U1 U1 = U1++instance Monoid a => Monoid' (K1 i a) where+  mempty' = K1 mempty+  mappend' (K1 x) (K1 y) = K1 (x `mappend` y)++instance Monoid' f => Monoid' (M1 i c f) where+  mempty' = M1 mempty'+  mappend' (M1 x) (M1 y) = M1 (x `mappend'` y)++instance (Monoid' f, Monoid' h) => Monoid' (f :*: h) where+  mempty' = mempty' :*: mempty'+  mappend' (x1 :*: y1) (x2 :*: y2) = mappend' x1 x2 :*: mappend' y1 y2++--------------------------------------------------------------------------------++memptydefault :: (Generic a, Monoid' (Rep a)) => a+memptydefault = to mempty'++mappenddefault :: (Generic a, Monoid' (Rep a)) => a -> a -> a+mappenddefault x y = to (mappend' (from x) (from y))++--------------------------------------------------------------------------------++class GSemigroup a => GMonoid a where++  -- | Generic 'mempty'+  gmempty  :: a++  -- | Generic 'mappend'+  gmappend :: a -> a -> a++  -- | Generic 'mconcat'+  gmconcat :: [a] -> a+  gmconcat = foldr gmappend gmempty++  default gmempty :: (Generic a, GMonoid' (Rep a)) => a+  gmempty = to gmempty'++  default gmappend :: (Generic a, GMonoid' (Rep a)) => a -> a -> a+  gmappend x y = to (gmappend' (from x) (from y))++--------------------------------------------------------------------------------++-- Instances that reuse Monoid+instance GMonoid Ordering where+  gmempty = mempty+  gmappend = mappend+instance GMonoid () where+  gmempty = mempty+  gmappend = mappend+instance GMonoid Any where+  gmempty = mempty+  gmappend = mappend+instance GMonoid All where+  gmempty = mempty+  gmappend = mappend+instance GMonoid (First a) where+  gmempty = mempty+  gmappend = mappend+instance GMonoid (Last a) where+  gmempty = mempty+  gmappend = mappend+instance Num a => GMonoid (Sum a) where+  gmempty = mempty+  gmappend = mappend+instance Num a => GMonoid (Product a) where+  gmempty = mempty+  gmappend = mappend+instance GMonoid [a] where+  gmempty  = mempty+  gmappend = mappend+instance GMonoid (Endo a) where+  gmempty = mempty+  gmappend = mappend+instance Alternative f => GMonoid (Alt f a) where+  gmempty = mempty+  gmappend = mappend++-- Handwritten instances+instance GMonoid a => GMonoid (Dual a) where+  gmempty = Dual gmempty+  gmappend (Dual x) (Dual y) = Dual (gmappend y x)+instance GMonoid b => GMonoid (a -> b) where+  gmempty _ = gmempty+  gmappend f g x = gmappend (f x) (g x)+instance GMonoid a => GMonoid (Const a b) where+  gmempty  = gmemptydefault+  gmappend = gmappenddefault+instance GMonoid a => GMonoid (Down a) where+  gmempty  = gmemptydefault+  gmappend = gmappenddefault++instance GMonoid (Proxy s) where+  gmempty  = memptydefault+  gmappend = mappenddefault++instance GMonoid a => GMonoid (Identity a) where+  gmempty  = gmemptydefault+  gmappend = gmappenddefault++-- Tuple instances+instance (GMonoid a,GMonoid b) => GMonoid (a,b) where+  gmempty = (gmempty,gmempty)+  gmappend (a1,b1) (a2,b2) =+    (gmappend a1 a2,gmappend b1 b2)+instance (GMonoid a,GMonoid b,GMonoid c) => GMonoid (a,b,c) where+  gmempty = (gmempty,gmempty,gmempty)+  gmappend (a1,b1,c1) (a2,b2,c2) =+    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2)+instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d) => GMonoid (a,b,c,d) where+  gmempty = (gmempty,gmempty,gmempty,gmempty)+  gmappend (a1,b1,c1,d1) (a2,b2,c2,d2) =+    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2)+instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e) => GMonoid (a,b,c,d,e) where+  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty)+  gmappend (a1,b1,c1,d1,e1) (a2,b2,c2,d2,e2) =+    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2)+instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e,GMonoid f) => GMonoid (a,b,c,d,e,f) where+  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty,gmempty)+  gmappend (a1,b1,c1,d1,e1,f1) (a2,b2,c2,d2,e2,f2) =+    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2,gmappend f1 f2)+instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e,GMonoid f,GMonoid g) => GMonoid (a,b,c,d,e,f,g) where+  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty,gmempty,gmempty)+  gmappend (a1,b1,c1,d1,e1,f1,g1) (a2,b2,c2,d2,e2,f2,g2) =+    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2,gmappend f1 f2,gmappend g1 g2)+instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e,GMonoid f,GMonoid g,GMonoid h) => GMonoid (a,b,c,d,e,f,g,h) where+  gmempty = (gmempty,gmempty,gmempty,gmempty,gmempty,gmempty,gmempty,gmempty)+  gmappend (a1,b1,c1,d1,e1,f1,g1,h1) (a2,b2,c2,d2,e2,f2,g2,h2) =+    (gmappend a1 a2,gmappend b1 b2,gmappend c1 c2,gmappend d1 d2,gmappend e1 e2,gmappend f1 f2,gmappend g1 g2,gmappend h1 h2)
+ src/Generics/Deriving/Semigroup.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE Safe #-}+{-# OPTIONS_GHC -Wno-orphans #-}++module Generics.Deriving.Semigroup (module Generics.Deriving.Semigroup.Internal) where++import Data.Semigroup (WrappedMonoid(..))++import Generics.Deriving.Monoid.Internal (GMonoid(..))+import Generics.Deriving.Semigroup.Internal++instance GMonoid m => GSemigroup (WrappedMonoid m) where+  gsappend (WrapMonoid a) (WrapMonoid b) = WrapMonoid (gmappend a b)
+ src/Generics/Deriving/Semigroup/Internal.hs view
@@ -0,0 +1,167 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeOperators #-}++module Generics.Deriving.Semigroup.Internal (+  -- * Generic semigroup class+    GSemigroup(..)++  -- * Default definition+  , gsappenddefault++  -- * Internal semigroup class+  , GSemigroup'(..)++  ) where++import Control.Applicative+import Data.Functor.Identity (Identity)+import Data.List.NonEmpty (NonEmpty(..))+import Data.Monoid as Monoid hiding ((<>))+import Data.Ord (Down)+import Data.Proxy (Proxy)+import Data.Semigroup as Semigroup+import Data.Void (Void)+import Generics.Deriving.Base++-------------------------------------------------------------------------------++infixr 6 `gsappend'`+class GSemigroup' f where+  gsappend' :: f x -> f x -> f x++instance GSemigroup' U1 where+  gsappend' U1 U1 = U1++instance GSemigroup a => GSemigroup' (K1 i a) where+  gsappend' (K1 x) (K1 y) = K1 (gsappend x y)++instance GSemigroup' f => GSemigroup' (M1 i c f) where+  gsappend' (M1 x) (M1 y) = M1 (gsappend' x y)++instance (GSemigroup' f, GSemigroup' g) => GSemigroup' (f :*: g) where+  gsappend' (x1 :*: y1) (x2 :*: y2) = gsappend' x1 x2 :*: gsappend' y1 y2++-------------------------------------------------------------------------------++infixr 6 `gsappend`+class GSemigroup a where+  gsappend :: a -> a -> a+  default gsappend :: (Generic a, GSemigroup' (Rep a)) => a -> a -> a+  gsappend = gsappenddefault++  gstimes :: Integral b => b -> a -> a+  gstimes y0 x0+    | y0 <= 0   = error "gstimes: positive multiplier expected"+    | otherwise = f x0 y0+    where+      f x y+        | even y = f (gsappend x x) (y `quot` 2)+        | y == 1 = x+        | otherwise = g (gsappend x x) (pred y  `quot` 2) x+      g x y z+        | even y = g (gsappend x x) (y `quot` 2) z+        | y == 1 = gsappend x z+        | otherwise = g (gsappend x x) (pred y `quot` 2) (gsappend x z)++  gsconcat :: NonEmpty a -> a+  gsconcat (a :| as) = go a as where+    go b (c:cs) = gsappend b (go c cs)+    go b []     = b++infixr 6 `gsappenddefault`+gsappenddefault :: (Generic a, GSemigroup' (Rep a)) => a -> a -> a+gsappenddefault x y = to (gsappend' (from x) (from y))++-------------------------------------------------------------------------------++-- Instances that reuse Monoid+instance GSemigroup Ordering where+  gsappend = mappend+instance GSemigroup () where+  gsappend = mappend+instance GSemigroup Any where+  gsappend = mappend+instance GSemigroup All where+  gsappend = mappend+instance GSemigroup (Monoid.First a) where+  gsappend = mappend+instance GSemigroup (Monoid.Last a) where+  gsappend = mappend+instance Num a => GSemigroup (Sum a) where+  gsappend = mappend+instance Num a => GSemigroup (Product a) where+  gsappend = mappend+instance GSemigroup [a] where+  gsappend = mappend+instance GSemigroup (Endo a) where+  gsappend = mappend+instance Alternative f => GSemigroup (Alt f a) where+  gsappend = mappend++-- Handwritten instances+instance GSemigroup a => GSemigroup (Dual a) where+  gsappend (Dual x) (Dual y) = Dual (gsappend y x)+instance GSemigroup a => GSemigroup (Maybe a) where+  gsappend Nothing  x        = x+  gsappend x        Nothing  = x+  gsappend (Just x) (Just y) = Just (gsappend x y)+instance GSemigroup b => GSemigroup (a -> b) where+  gsappend f g x = gsappend (f x) (g x)+instance GSemigroup a => GSemigroup (Const a b) where+  gsappend = gsappenddefault+instance GSemigroup a => GSemigroup (Down a) where+  gsappend = gsappenddefault+instance GSemigroup (Either a b) where+  gsappend Left{} b = b+  gsappend a      _ = a++instance GSemigroup (Proxy s) where+  gsappend    = gsappenddefault++instance GSemigroup a => GSemigroup (Identity a) where+  gsappend = gsappenddefault++instance GSemigroup Void where+  gsappend a _ = a++instance GSemigroup (Semigroup.First a) where+  gsappend = (<>)++instance GSemigroup (Semigroup.Last a) where+  gsappend = (<>)++instance Ord a => GSemigroup (Max a) where+  gsappend = (<>)++instance Ord a => GSemigroup (Min a) where+  gsappend = (<>)++instance GSemigroup (NonEmpty a) where+  gsappend = (<>)++-- Tuple instances+instance (GSemigroup a,GSemigroup b) => GSemigroup (a,b) where+  gsappend (a1,b1) (a2,b2) =+    (gsappend a1 a2,gsappend b1 b2)+instance (GSemigroup a,GSemigroup b,GSemigroup c) => GSemigroup (a,b,c) where+  gsappend (a1,b1,c1) (a2,b2,c2) =+    (gsappend a1 a2,gsappend b1 b2,gsappend c1 c2)+instance (GSemigroup a,GSemigroup b,GSemigroup c,GSemigroup d) => GSemigroup (a,b,c,d) where+  gsappend (a1,b1,c1,d1) (a2,b2,c2,d2) =+    (gsappend a1 a2,gsappend b1 b2,gsappend c1 c2,gsappend d1 d2)+instance (GSemigroup a,GSemigroup b,GSemigroup c,GSemigroup d,GSemigroup e) => GSemigroup (a,b,c,d,e) where+  gsappend (a1,b1,c1,d1,e1) (a2,b2,c2,d2,e2) =+    (gsappend a1 a2,gsappend b1 b2,gsappend c1 c2,gsappend d1 d2,gsappend e1 e2)+instance (GSemigroup a,GSemigroup b,GSemigroup c,GSemigroup d,GSemigroup e,GSemigroup f) => GSemigroup (a,b,c,d,e,f) where+  gsappend (a1,b1,c1,d1,e1,f1) (a2,b2,c2,d2,e2,f2) =+    (gsappend a1 a2,gsappend b1 b2,gsappend c1 c2,gsappend d1 d2,gsappend e1 e2,gsappend f1 f2)+instance (GSemigroup a,GSemigroup b,GSemigroup c,GSemigroup d,GSemigroup e,GSemigroup f,GSemigroup g) => GSemigroup (a,b,c,d,e,f,g) where+  gsappend (a1,b1,c1,d1,e1,f1,g1) (a2,b2,c2,d2,e2,f2,g2) =+    (gsappend a1 a2,gsappend b1 b2,gsappend c1 c2,gsappend d1 d2,gsappend e1 e2,gsappend f1 f2,gsappend g1 g2)+instance (GSemigroup a,GSemigroup b,GSemigroup c,GSemigroup d,GSemigroup e,GSemigroup f,GSemigroup g,GSemigroup h) => GSemigroup (a,b,c,d,e,f,g,h) where+  gsappend (a1,b1,c1,d1,e1,f1,g1,h1) (a2,b2,c2,d2,e2,f2,g2,h2) =+    (gsappend a1 a2,gsappend b1 b2,gsappend c1 c2,gsappend d1 d2,gsappend e1 e2,gsappend f1 f2,gsappend g1 g2,gsappend h1 h2)
src/Generics/Deriving/Show.hs view
@@ -1,142 +1,606 @@-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE OverlappingInstances #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
-module Generics.Deriving.Show (
-  -- * Generic show class
-    GShow(..)
-
-  -- * Default definition
-  , gshowsPrecdefault
-
-  ) where
-
-
-import Generics.Deriving.Base
-import Generics.Deriving.Instances ()
-
---------------------------------------------------------------------------------
--- Generic show
---------------------------------------------------------------------------------
-
-appPrec :: Int
-appPrec = 2
-
-data Type = Rec | Tup | Pref | Inf String
-
-class GShow' f where
-  gshowsPrec' :: Type -> Int -> f a -> ShowS
-  isNullary   :: f a -> Bool
-  isNullary = error "generic show (isNullary): unnecessary case"
-
-instance GShow' U1 where
-  gshowsPrec' _ _ U1 = id
-  isNullary _ = True
-
-instance (GShow c) => GShow' (K1 i c) where
-  gshowsPrec' _ n (K1 a) = gshowsPrec n a
-  isNullary _ = False
-
--- No instances for P or Rec because gshow is only applicable to types of kind *
-
-instance (GShow' a, Constructor c) => GShow' (M1 C c a) where
-  gshowsPrec' _ n c@(M1 x) = 
-    case fixity of
-      Prefix    -> showParen (n > appPrec && not (isNullary x)) 
-                    ( showString (conName c) 
-                    . if (isNullary x) then id else showChar ' '
-                    . showBraces t (gshowsPrec' t appPrec x))
-      Infix _ m -> showParen (n > m) (showBraces t (gshowsPrec' t m x))
-      where fixity = conFixity c
-            t = if (conIsRecord c) then Rec else
-                  case (conIsTuple c) of
-                    True -> Tup
-                    False -> case fixity of
-                                Prefix    -> Pref
-                                Infix _ _ -> Inf (show (conName c))
-            showBraces :: Type -> ShowS -> ShowS
-            showBraces Rec     p = showChar '{' . p . showChar '}'
-            showBraces Tup     p = showChar '(' . p . showChar ')'
-            showBraces Pref    p = p
-            showBraces (Inf _) p = p
-            conIsTuple y = tupleName (conName y) where
-              tupleName ('(':',':_) = True
-              tupleName _           = False
-
-instance (Selector s, GShow' a) => GShow' (M1 S s a) where
-  gshowsPrec' t n s@(M1 x) | selName s == "" = --showParen (n > appPrec)
-                                                 (gshowsPrec' t n x)
-                           | otherwise       =   showString (selName s)
-                                               . showString " = "
-                                               . gshowsPrec' t 0 x
-  isNullary (M1 x) = isNullary x
-
-instance (GShow' a) => GShow' (M1 D d a) where
-  gshowsPrec' t n (M1 x) = gshowsPrec' t n x
-
-instance (GShow' a, GShow' b) => GShow' (a :+: b) where
-  gshowsPrec' t n (L1 x) = gshowsPrec' t n x
-  gshowsPrec' t n (R1 x) = gshowsPrec' t n x
-
-instance (GShow' a, GShow' b) => GShow' (a :*: b) where
-  gshowsPrec' t@Rec     n (a :*: b) =
-    gshowsPrec' t n     a . showString ", " . gshowsPrec' t n     b
-  gshowsPrec' t@(Inf s) n (a :*: b) =
-    gshowsPrec' t n     a . showString s    . gshowsPrec' t n     b
-  gshowsPrec' t@Tup     n (a :*: b) =
-    gshowsPrec' t n     a . showChar ','    . gshowsPrec' t n     b
-  gshowsPrec' t@Pref    n (a :*: b) =
-    gshowsPrec' t (n+1) a . showChar ' '    . gshowsPrec' t (n+1) b
-  
-  -- If we have a product then it is not a nullary constructor
-  isNullary _ = False
-
-
-class GShow a where 
-  gshowsPrec :: Int -> a -> ShowS
-  gshows :: a -> ShowS
-  gshows = gshowsPrec 0
-  gshow :: a -> String
-  gshow x = gshows x ""
-#if __GLASGOW_HASKELL__ >= 701
-  default gshowsPrec :: (Generic a, GShow' (Rep a))
-                     => Int -> a -> ShowS
-  gshowsPrec = gshowsPrecdefault
-
-instance (GShow a) => GShow (Maybe a)
-
-#else
-
-instance (GShow a) => GShow (Maybe a) where
-  gshowsPrec = gshowsPrecdefault
-
-#endif
-
-gshowsPrecdefault :: (Generic a, GShow' (Rep a))
-                  => Int -> a -> ShowS
-gshowsPrecdefault n = gshowsPrec' Pref n . from
-
-
--- Base types instances
-instance GShow Char   where gshowsPrec = showsPrec
-instance GShow Int    where gshowsPrec = showsPrec
-instance GShow Float  where gshowsPrec = showsPrec
-instance GShow String where gshowsPrec = showsPrec
-instance GShow Bool   where gshowsPrec = showsPrec
-
-intersperse :: a -> [a] -> [a]
-intersperse _ []    = []
-intersperse _ [h]   = [h]
-intersperse x (h:t) = h : x : (intersperse x t)
-
-instance (GShow a) => GShow [a] where
-  gshowsPrec _ l =   showChar '['
-                   . foldr (.) id
-                      (intersperse (showChar ',') (map (gshowsPrec 0) l))
-                   . showChar ']'
+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Generics.Deriving.Show (+  -- * Generic show class+    GShow(..)++  -- * Default definition+  , gshowsPrecdefault++  -- * Internal show class+  , GShow'(..)++  ) where++import           Control.Applicative (Const, ZipList)++import           Data.Char (GeneralCategory)+import           Data.Complex (Complex)+import           Data.Functor.Identity (Identity)+import           Data.Int+import           Data.List.NonEmpty (NonEmpty)+import           Data.Monoid (All, Alt, Any, Dual, Product, Sum)+import qualified Data.Monoid as Monoid (First, Last)+import           Data.Proxy (Proxy)+import qualified Data.Semigroup as Semigroup (First, Last)+import           Data.Semigroup (Arg, Max, Min, WrappedMonoid)+import           Data.Version (Version)+import           Data.Void (Void)+import           Data.Word++import           Foreign.C.Types+import           Foreign.ForeignPtr (ForeignPtr)+import           Foreign.Ptr++import           Generics.Deriving.Base++import           GHC.Exts hiding (Any)++import           Numeric.Natural (Natural)++import           System.Exit (ExitCode)+import           System.IO (BufferMode, Handle, HandlePosn, IOMode, SeekMode)+import           System.IO.Error (IOErrorType)+import           System.Posix.Types++--------------------------------------------------------------------------------+-- Generic show+--------------------------------------------------------------------------------++intersperse :: a -> [a] -> [a]+intersperse _ []    = []+intersperse _ [h]   = [h]+intersperse x (h:t) = h : x : (intersperse x t)++appPrec :: Int+appPrec = 2++data Type = Rec | Tup | Pref | Inf String++class GShow' f where+  gshowsPrec' :: Type -> Int -> f a -> ShowS+  isNullary   :: f a -> Bool+  isNullary = error "generic show (isNullary): unnecessary case"++instance GShow' V1 where+  gshowsPrec' _ _ x = case x of {}++instance GShow' U1 where+  gshowsPrec' _ _ U1 = id+  isNullary _ = True++instance (GShow c) => GShow' (K1 i c) where+  gshowsPrec' _ n (K1 a) = gshowsPrec n a+  isNullary _ = False++-- No instances for P or Rec because gshow is only applicable to types of kind *++instance (GShow' a, Constructor c) => GShow' (M1 C c a) where+  gshowsPrec' _ n c@(M1 x) =+    case fixity of+      Prefix    -> showParen (n > appPrec && not (isNullary x))+                    ( showString (conName c)+                    . if (isNullary x) then id else showChar ' '+                    . showBraces t (gshowsPrec' t appPrec x))+      Infix _ m -> showParen (n > m) (showBraces t (gshowsPrec' t m x))+      where fixity = conFixity c+            t = if (conIsRecord c) then Rec else+                  case (conIsTuple c) of+                    True -> Tup+                    False -> case fixity of+                                Prefix    -> Pref+                                Infix _ _ -> Inf (show (conName c))+            showBraces :: Type -> ShowS -> ShowS+            showBraces Rec     p = showChar '{' . p . showChar '}'+            showBraces Tup     p = showChar '(' . p . showChar ')'+            showBraces Pref    p = p+            showBraces (Inf _) p = p++            conIsTuple :: C1 c f p -> Bool+            conIsTuple y = tupleName (conName y) where+              tupleName ('(':',':_) = True+              tupleName _           = False++instance (Selector s, GShow' a) => GShow' (M1 S s a) where+  gshowsPrec' t n s@(M1 x) | selName s == "" = --showParen (n > appPrec)+                                                 (gshowsPrec' t n x)+                           | otherwise       =   showString (selName s)+                                               . showString " = "+                                               . gshowsPrec' t 0 x+  isNullary (M1 x) = isNullary x++instance (GShow' a) => GShow' (M1 D d a) where+  gshowsPrec' t n (M1 x) = gshowsPrec' t n x++instance (GShow' a, GShow' b) => GShow' (a :+: b) where+  gshowsPrec' t n (L1 x) = gshowsPrec' t n x+  gshowsPrec' t n (R1 x) = gshowsPrec' t n x++instance (GShow' a, GShow' b) => GShow' (a :*: b) where+  gshowsPrec' t@Rec     n (a :*: b) =+    gshowsPrec' t n     a . showString ", " . gshowsPrec' t n     b+  gshowsPrec' t@(Inf s) n (a :*: b) =+    gshowsPrec' t n     a . showString s    . gshowsPrec' t n     b+  gshowsPrec' t@Tup     n (a :*: b) =+    gshowsPrec' t n     a . showChar ','    . gshowsPrec' t n     b+  gshowsPrec' t@Pref    n (a :*: b) =+    gshowsPrec' t (n+1) a . showChar ' '    . gshowsPrec' t (n+1) b++  -- If we have a product then it is not a nullary constructor+  isNullary _ = False++-- Unboxed types+instance GShow' UChar where+  gshowsPrec' _ _ (UChar c)   = showsPrec 0 (C# c) . showChar '#'+instance GShow' UDouble where+  gshowsPrec' _ _ (UDouble d) = showsPrec 0 (D# d) . showString "##"+instance GShow' UFloat where+  gshowsPrec' _ _ (UFloat f)  = showsPrec 0 (F# f) . showChar '#'+instance GShow' UInt where+  gshowsPrec' _ _ (UInt i)    = showsPrec 0 (I# i) . showChar '#'+instance GShow' UWord where+  gshowsPrec' _ _ (UWord w)   = showsPrec 0 (W# w) . showString "##"+++class GShow a where+  gshowsPrec :: Int -> a -> ShowS+  default gshowsPrec :: (Generic a, GShow' (Rep a))+                     => Int -> a -> ShowS+  gshowsPrec = gshowsPrecdefault++  gshows :: a -> ShowS+  gshows = gshowsPrec 0++  gshow :: a -> String+  gshow x = gshows x ""++  gshowList :: [a] -> ShowS+  gshowList l =   showChar '['+                . foldr (.) id+                   (intersperse (showChar ',') (map (gshowsPrec 0) l))+                . showChar ']'++gshowsPrecdefault :: (Generic a, GShow' (Rep a))+                  => Int -> a -> ShowS+gshowsPrecdefault n = gshowsPrec' Pref n . from+++-- Base types instances+-- Base types instances+instance GShow () where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b) => GShow (a, b) where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b, GShow c) => GShow (a, b, c) where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b, GShow c, GShow d) => GShow (a, b, c, d) where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b, GShow c, GShow d, GShow e) => GShow (a, b, c, d, e) where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b, GShow c, GShow d, GShow e, GShow f)+    => GShow (a, b, c, d, e, f) where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b, GShow c, GShow d, GShow e, GShow f, GShow g)+    => GShow (a, b, c, d, e, f, g) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow [a] where+  gshowsPrec _ = gshowList++instance (GShow (f p), GShow (g p)) => GShow ((f :+: g) p) where+  gshowsPrec = gshowsPrecdefault++instance (GShow (f p), GShow (g p)) => GShow ((f :*: g) p) where+  gshowsPrec = gshowsPrecdefault++instance GShow (f (g p)) => GShow ((f :.: g) p) where+  gshowsPrec = gshowsPrecdefault++instance GShow All where+  gshowsPrec = gshowsPrecdefault++instance GShow (f a) => GShow (Alt f a) where+  gshowsPrec = gshowsPrecdefault++instance GShow Any where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b) => GShow (Arg a b) where+  gshowsPrec = gshowsPrecdefault++instance GShow Associativity where+  gshowsPrec = gshowsPrecdefault++instance GShow Bool where+  gshowsPrec = gshowsPrecdefault++instance GShow BufferMode where+  gshowsPrec = showsPrec++#if defined(HTYPE_CC_T)+instance GShow CCc where+  gshowsPrec = showsPrec+#endif++instance GShow CChar where+  gshowsPrec = showsPrec++instance GShow CClock where+  gshowsPrec = showsPrec++#if defined(HTYPE_DEV_T)+instance GShow CDev where+  gshowsPrec = showsPrec+#endif++instance GShow CDouble where+  gshowsPrec = showsPrec++instance GShow CFloat where+  gshowsPrec = showsPrec++#if defined(HTYPE_GID_T)+instance GShow CGid where+  gshowsPrec = showsPrec+#endif++instance GShow Char where+  gshowsPrec = showsPrec+  gshowList  = showList++#if defined(HTYPE_INO_T)+instance GShow CIno where+  gshowsPrec = showsPrec+#endif++instance GShow CInt where+  gshowsPrec = showsPrec++instance GShow CIntMax where+  gshowsPrec = showsPrec++instance GShow CIntPtr where+  gshowsPrec = showsPrec++instance GShow CLLong where+  gshowsPrec = showsPrec++instance GShow CLong where+  gshowsPrec = showsPrec++#if defined(HTYPE_MODE_T)+instance GShow CMode where+  gshowsPrec = showsPrec+#endif++#if defined(HTYPE_NLINK_T)+instance GShow CNlink where+  gshowsPrec = showsPrec+#endif++#if defined(HTYPE_OFF_T)+instance GShow COff where+  gshowsPrec = showsPrec+#endif++instance GShow a => GShow (Complex a) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Const a b) where+  gshowsPrec = gshowsPrecdefault++#if defined(HTYPE_PID_T)+instance GShow CPid where+  gshowsPrec = showsPrec+#endif++instance GShow CPtrdiff where+  gshowsPrec = showsPrec++#if defined(HTYPE_RLIM_T)+instance GShow CRLim where+  gshowsPrec = showsPrec+#endif++instance GShow CSChar where+  gshowsPrec = showsPrec++#if defined(HTYPE_SPEED_T)+instance GShow CSpeed where+  gshowsPrec = showsPrec+#endif++instance GShow CSUSeconds where+  gshowsPrec = showsPrec++instance GShow CShort where+  gshowsPrec = showsPrec++instance GShow CSigAtomic where+  gshowsPrec = showsPrec++instance GShow CSize where+  gshowsPrec = showsPrec++#if defined(HTYPE_SSIZE_T)+instance GShow CSsize where+  gshowsPrec = showsPrec+#endif++#if defined(HTYPE_TCFLAG_T)+instance GShow CTcflag where+  gshowsPrec = showsPrec+#endif++instance GShow CTime where+  gshowsPrec = showsPrec++instance GShow CUChar where+  gshowsPrec = showsPrec++#if defined(HTYPE_UID_T)+instance GShow CUid where+  gshowsPrec = showsPrec+#endif++instance GShow CUInt where+  gshowsPrec = showsPrec++instance GShow CUIntMax where+  gshowsPrec = showsPrec++instance GShow CUIntPtr where+  gshowsPrec = showsPrec++instance GShow CULLong where+  gshowsPrec = showsPrec++instance GShow CULong where+  gshowsPrec = showsPrec++instance GShow CUSeconds where+  gshowsPrec = showsPrec++instance GShow CUShort where+  gshowsPrec = showsPrec++instance GShow CWchar where+  gshowsPrec = showsPrec++instance GShow Double where+  gshowsPrec = showsPrec++instance GShow a => GShow (Down a) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Dual a) where+  gshowsPrec = gshowsPrecdefault++instance (GShow a, GShow b) => GShow (Either a b) where+  gshowsPrec = gshowsPrecdefault++instance GShow ExitCode where+  gshowsPrec = gshowsPrecdefault++instance GShow Fd where+  gshowsPrec = showsPrec++instance GShow a => GShow (Monoid.First a) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Semigroup.First a) where+  gshowsPrec = gshowsPrecdefault++instance GShow Fixity where+  gshowsPrec = gshowsPrecdefault++instance GShow Float where+  gshowsPrec = showsPrec++instance GShow (ForeignPtr a) where+  gshowsPrec = showsPrec++instance GShow (FunPtr a) where+  gshowsPrec = showsPrec++instance GShow GeneralCategory where+  gshowsPrec = showsPrec++instance GShow Handle where+  gshowsPrec = showsPrec++instance GShow HandlePosn where+  gshowsPrec = showsPrec++instance GShow a => GShow (Identity a) where+  gshowsPrec = gshowsPrecdefault++instance GShow Int where+  gshowsPrec = showsPrec++instance GShow Int8 where+  gshowsPrec = showsPrec++instance GShow Int16 where+  gshowsPrec = showsPrec++instance GShow Int32 where+  gshowsPrec = showsPrec++instance GShow Int64 where+  gshowsPrec = showsPrec++instance GShow Integer where+  gshowsPrec = showsPrec++instance GShow IntPtr where+  gshowsPrec = showsPrec++instance GShow IOError where+  gshowsPrec = showsPrec++instance GShow IOErrorType where+  gshowsPrec = showsPrec++instance GShow IOMode where+  gshowsPrec = showsPrec++instance GShow c => GShow (K1 i c p) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Monoid.Last a) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Semigroup.Last a) where+  gshowsPrec = gshowsPrecdefault++instance GShow (f p) => GShow (M1 i c f p) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Max a) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Maybe a) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Min a) where+  gshowsPrec = gshowsPrecdefault++instance GShow Natural where+  gshowsPrec = showsPrec++instance GShow a => GShow (NonEmpty a) where+  gshowsPrec = gshowsPrecdefault++instance GShow Ordering where+  gshowsPrec = gshowsPrecdefault++instance GShow p => GShow (Par1 p) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (Product a) where+  gshowsPrec = gshowsPrecdefault++instance GShow (Proxy s) where+  gshowsPrec = gshowsPrecdefault++instance GShow (Ptr a) where+  gshowsPrec = showsPrec++instance GShow (f p) => GShow (Rec1 f p) where+  gshowsPrec = gshowsPrecdefault++instance GShow SeekMode where+  gshowsPrec = showsPrec++instance GShow a => GShow (Sum a) where+  gshowsPrec = gshowsPrecdefault++instance GShow (U1 p) where+  gshowsPrec = gshowsPrecdefault++instance GShow (UChar p) where+  gshowsPrec = gshowsPrecdefault++instance GShow (UDouble p) where+  gshowsPrec = gshowsPrecdefault++instance GShow (UFloat p) where+  gshowsPrec = gshowsPrecdefault++instance GShow (UInt p) where+  gshowsPrec = gshowsPrecdefault++instance GShow (UWord p) where+  gshowsPrec = gshowsPrecdefault++instance GShow Version where+  gshowsPrec = gshowsPrecdefault++instance GShow Void where+  gshowsPrec = showsPrec++instance GShow Word where+  gshowsPrec = showsPrec++instance GShow Word8 where+  gshowsPrec = showsPrec++instance GShow Word16 where+  gshowsPrec = showsPrec++instance GShow Word32 where+  gshowsPrec = showsPrec++instance GShow Word64 where+  gshowsPrec = showsPrec++instance GShow WordPtr where+  gshowsPrec = showsPrec++instance GShow m => GShow (WrappedMonoid m) where+  gshowsPrec = gshowsPrecdefault++instance GShow a => GShow (ZipList a) where+  gshowsPrec = gshowsPrecdefault++#if MIN_VERSION_base(4,10,0)+instance GShow CBool where+  gshowsPrec = showsPrec++# if defined(HTYPE_BLKSIZE_T)+instance GShow CBlkSize where+  gshowsPrec = showsPrec+# endif++# if defined(HTYPE_BLKCNT_T)+instance GShow CBlkCnt where+  gshowsPrec = showsPrec+# endif++# if defined(HTYPE_CLOCKID_T)+instance GShow CClockId where+  gshowsPrec = showsPrec+# endif++# if defined(HTYPE_FSBLKCNT_T)+instance GShow CFsBlkCnt where+  gshowsPrec = showsPrec+# endif++# if defined(HTYPE_FSFILCNT_T)+instance GShow CFsFilCnt where+  gshowsPrec = showsPrec+# endif++# if defined(HTYPE_ID_T)+instance GShow CId where+  gshowsPrec = showsPrec+# endif++# if defined(HTYPE_KEY_T)+instance GShow CKey where+  gshowsPrec = showsPrec+# endif++# if defined(HTYPE_TIMER_T)+instance GShow CTimer where+  gshowsPrec = showsPrec+# endif+#endif
src/Generics/Deriving/TH.hs view
@@ -1,415 +1,1206 @@-{-# LANGUAGE TemplateHaskell, CPP #-}
-{-# OPTIONS_GHC -w           #-}
-
------------------------------------------------------------------------------
--- |
--- Module      :  Generics.Deriving.TH
--- Copyright   :  (c) 2008--2009 Universiteit Utrecht
--- License     :  BSD3
---
--- Maintainer  :  generics@haskell.org
--- Stability   :  experimental
--- Portability :  non-portable
---
--- This module contains Template Haskell code that can be used to
--- automatically generate the boilerplate code for the generic deriving
--- library. For now, it generates only the 'Generic' instance.
--- Empty datatypes are not yet supported.
------------------------------------------------------------------------------
-
--- Adapted from Generics.Regular.TH
-module Generics.Deriving.TH (
-      
-      deriveMeta
-    , deriveData
-    , deriveConstructors
-    , deriveSelectors
-
-#if __GLASGOW_HASKELL__ < 701
-    , deriveAll
-    , deriveRepresentable0
-    , deriveRep0
-    , simplInstance
-#endif
-  ) where
-
-import Generics.Deriving.Base
-
-import Language.Haskell.TH hiding (Fixity())
-import Language.Haskell.TH.Syntax (Lift(..))
-
-import Data.List (intercalate)
-import Control.Monad
-
--- | Given the names of a generic class, a type to instantiate, a function in
--- the class and the default implementation, generates the code for a basic
--- generic instance.
-simplInstance :: Name -> Name -> Name -> Name -> Q [Dec]
-simplInstance cl ty fn df = do
-  i <- reify (genRepName 0 ty)
-  x <- newName "x"
-  let typ = ForallT [PlainTV x] [] 
-        ((foldl (\a -> AppT a . VarT . tyVarBndrToName) (ConT (genRepName 0 ty)) 
-          (typeVariables i)) `AppT` (VarT x))
-  fmap (: []) $ instanceD (cxt []) (conT cl `appT` conT ty)
-    [funD fn [clause [] (normalB (varE df `appE` 
-      (sigE (global 'undefined) (return typ)))) []]]
-
-
--- | Given the type and the name (as string) for the type to derive,
--- generate the 'Data' instance, the 'Constructor' instances, the 'Selector'
--- instances, and the 'Representable0' instance.
-deriveAll :: Name -> Q [Dec]
-deriveAll n =
-  do a <- deriveMeta n
-     b <- deriveRepresentable0 n
-     return (a ++ b)
-
--- | Given the type and the name (as string) for the type to derive,
--- generate the 'Data' instance, the 'Constructor' instances, and the 'Selector'
--- instances.
-deriveMeta :: Name -> Q [Dec]
-deriveMeta n =
-  do a <- deriveData n
-     b <- deriveConstructors n
-     c <- deriveSelectors n
-     return (a ++ b ++ c)
-
--- | Given a datatype name, derive a datatype and instance of class 'Datatype'.
-deriveData :: Name -> Q [Dec]
-deriveData = dataInstance
-
--- | Given a datatype name, derive datatypes and 
--- instances of class 'Constructor'.
-deriveConstructors :: Name -> Q [Dec]
-deriveConstructors = constrInstance
-
--- | Given a datatype name, derive datatypes and instances of class 'Selector'.
-deriveSelectors :: Name -> Q [Dec]
-deriveSelectors = selectInstance
-
--- | Given the type and the name (as string) for the Representable0 type
--- synonym to derive, generate the 'Representable0' instance.
-deriveRepresentable0 :: Name -> Q [Dec]
-deriveRepresentable0 n = do
-    rep0 <- deriveRep0 n
-    inst <- deriveInst n
-    return $ rep0 ++ inst
-
--- | Derive only the 'Rep0' type synonym. Not needed if 'deriveRepresentable0'
--- is used.
-deriveRep0 :: Name -> Q [Dec]
-deriveRep0 n = do
-  i <- reify n
-  fmap (:[]) $ tySynD (genRepName 0 n) (typeVariables i) (rep0Type n)
-
-deriveInst :: Name -> Q [Dec]
-deriveInst t = do
-  i <- reify t
-  let typ q = foldl (\a -> AppT a . VarT . tyVarBndrToName) (ConT q) 
-                (typeVariables i)
-#if __GLASGOW_HASKELL__ >= 707
-  let tyIns = TySynInstD ''Rep (fmap (TySynEqn [typ (genRepName 0 t)]) [typ t])
-#else
-  let tyIns = TySynInstD ''Rep [typ t] (typ (genRepName 0 t))
-#endif
-  fcs <- mkFrom t 1 0 t
-  tcs <- mkTo   t 1 0 t
-  liftM (:[]) $
-    instanceD (cxt []) (conT ''Generic `appT` return (typ t))
-                         [return tyIns, funD 'from fcs, funD 'to tcs]
-
-
-dataInstance :: Name -> Q [Dec]
-dataInstance n = do
-  i <- reify n
-  case i of
-    TyConI (DataD    _ n _ _ _) -> mkInstance n
-    TyConI (NewtypeD _ n _ _ _) -> mkInstance n
-    _ -> return []
-  where
-    mkInstance n = do
-      ds <- mkDataData n
-      is <- mkDataInstance n
-      return $ [ds,is]
-
-constrInstance :: Name -> Q [Dec]
-constrInstance n = do
-  i <- reify n
-  case i of
-    TyConI (DataD    _ n _ cs _) -> mkInstance n cs
-    TyConI (NewtypeD _ n _ c  _) -> mkInstance n [c]
-    _ -> return []
-  where
-    mkInstance n cs = do
-      ds <- mapM (mkConstrData n) cs
-      is <- mapM (mkConstrInstance n) cs
-      return $ ds ++ is
-
-selectInstance :: Name -> Q [Dec]
-selectInstance n = do
-  i <- reify n
-  case i of
-    TyConI (DataD    _ n _ cs _) -> mkInstance n cs
-    TyConI (NewtypeD _ n _ c  _) -> mkInstance n [c]
-    _ -> return []
-  where
-    mkInstance n cs = do
-      ds <- mapM (mkSelectData n) cs
-      is <- mapM (mkSelectInstance n) cs
-      return $ concat (ds ++ is)
-
-typeVariables :: Info -> [TyVarBndr]
-typeVariables (TyConI (DataD    _ _ tv _ _)) = tv
-typeVariables (TyConI (NewtypeD _ _ tv _ _)) = tv
-typeVariables _                           = []
-
-tyVarBndrToName :: TyVarBndr -> Name
-tyVarBndrToName (PlainTV  name)   = name
-tyVarBndrToName (KindedTV name _) = name
-
-stripRecordNames :: Con -> Con
-stripRecordNames (RecC n f) =
-  NormalC n (map (\(_, s, t) -> (s, t)) f)
-stripRecordNames c = c
-
-genName :: [Name] -> Name
-genName = mkName . (++"_") . intercalate "_" . map nameBase
-
-genRepName :: Int -> Name -> Name
-genRepName n = mkName . (++"_") . (("Rep" ++ show n) ++) . nameBase
-
-mkDataData :: Name -> Q Dec
-mkDataData n = dataD (cxt []) (genName [n]) [] [] []
-
-mkConstrData :: Name -> Con -> Q Dec
-mkConstrData dt (NormalC n _) =
-  dataD (cxt []) (genName [dt, n]) [] [] [] 
-mkConstrData dt r@(RecC _ _) =
-  mkConstrData dt (stripRecordNames r)
-mkConstrData dt (InfixC t1 n t2) =
-  mkConstrData dt (NormalC n [t1,t2])
-
-mkSelectData :: Name -> Con -> Q [Dec]
-mkSelectData dt r@(RecC n fs) = return (map one fs)
-  where one (f, _, _) = DataD [] (genName [dt, n, f]) [] [] []
-mkSelectData dt _ = return []
-
-
-mkDataInstance :: Name -> Q Dec
-mkDataInstance n =
-  instanceD (cxt []) (appT (conT ''Datatype) (conT $ genName [n]))
-    [funD 'datatypeName [clause [wildP] (normalB (stringE (nameBase n))) []]
-    ,funD 'moduleName   [clause [wildP] (normalB (stringE name)) []]]
-  where
-    name = maybe (error "Cannot fetch module name!") id (nameModule n)
-
-instance Lift Fixity where
-  lift Prefix      = conE 'Prefix
-  lift (Infix a n) = conE 'Infix `appE` [| a |] `appE` [| n |]
-
-instance Lift Associativity where
-  lift LeftAssociative  = conE 'LeftAssociative
-  lift RightAssociative = conE 'RightAssociative
-  lift NotAssociative   = conE 'NotAssociative
-
-mkConstrInstance :: Name -> Con -> Q Dec
-mkConstrInstance dt (NormalC n _) = mkConstrInstanceWith dt n []
-mkConstrInstance dt (RecC    n _) = mkConstrInstanceWith dt n
-      [ funD 'conIsRecord [clause [wildP] (normalB (conE 'True)) []]]
-mkConstrInstance dt (InfixC t1 n t2) =
-    do
-      i <- reify n
-      let fi = case i of
-                 DataConI _ _ _ f -> convertFixity f
-                 _ -> Prefix
-      instanceD (cxt []) (appT (conT ''Constructor) (conT $ genName [dt, n]))
-        [funD 'conName   [clause [wildP] (normalB (stringE (nameBase n))) []],
-         funD 'conFixity [clause [wildP] (normalB [| fi |]) []]]
-  where
-    convertFixity (Fixity n d) = Infix (convertDirection d) n
-    convertDirection InfixL = LeftAssociative
-    convertDirection InfixR = RightAssociative
-    convertDirection InfixN = NotAssociative
-
-mkConstrInstanceWith :: Name -> Name -> [Q Dec] -> Q Dec
-mkConstrInstanceWith dt n extra = 
-  instanceD (cxt []) (appT (conT ''Constructor) (conT $ genName [dt, n]))
-    (funD 'conName [clause [wildP] (normalB (stringE (nameBase n))) []] : extra)
-
-mkSelectInstance :: Name -> Con -> Q [Dec]
-mkSelectInstance dt r@(RecC n fs) = return (map one fs) where
-  one (f, _, _) = 
-    InstanceD ([]) (AppT (ConT ''Selector) (ConT $ genName [dt, n, f]))
-      [FunD 'selName [Clause [WildP] 
-        (NormalB (LitE (StringL (nameBase f)))) []]]
-mkSelectInstance _ _ = return []
-
-rep0Type :: Name -> Q Type
-rep0Type n =
-    do
-      -- runIO $ putStrLn $ "processing " ++ show n
-      i <- reify n
-      let b = case i of
-                TyConI (DataD _ dt vs cs _) ->
-                  (conT ''D1) `appT` (conT $ genName [dt]) `appT` 
-                    (foldr1' sum (conT ''V1) 
-                      (map (rep0Con (dt, map tyVarBndrToName vs)) cs))
-                TyConI (NewtypeD _ dt vs c _) ->
-                  (conT ''D1) `appT` (conT $ genName [dt]) `appT`
-                    (rep0Con (dt, map tyVarBndrToName vs) c)
-                TyConI (TySynD t _ _) -> error "type synonym?" 
-                _ -> error "unknown construct" 
-      --appT b (conT $ mkName (nameBase n))
-      b where
-    sum :: Q Type -> Q Type -> Q Type
-    sum a b = conT ''(:+:) `appT` a `appT` b
-
-
-rep0Con :: (Name, [Name]) -> Con -> Q Type
-rep0Con (dt, vs) (NormalC n []) =
-    conT ''C1 `appT` (conT $ genName [dt, n]) `appT` 
-     (conT ''S1 `appT` conT ''NoSelector `appT` conT ''U1)
-rep0Con (dt, vs) (NormalC n fs) =
-    conT ''C1 `appT` (conT $ genName [dt, n]) `appT` 
-     (foldr1 prod (map (repField (dt, vs) . snd) fs)) where
-    prod :: Q Type -> Q Type -> Q Type
-    prod a b = conT ''(:*:) `appT` a `appT` b
-rep0Con (dt, vs) r@(RecC n []) =
-    conT ''C1 `appT` (conT $ genName [dt, n]) `appT` conT ''U1
-rep0Con (dt, vs) r@(RecC n fs) =
-    conT ''C1 `appT` (conT $ genName [dt, n]) `appT` 
-      (foldr1 prod (map (repField' (dt, vs) n) fs)) where
-    prod :: Q Type -> Q Type -> Q Type
-    prod a b = conT ''(:*:) `appT` a `appT` b
-
-rep0Con d (InfixC t1 n t2) = rep0Con d (NormalC n [t1,t2])
-
---dataDeclToType :: (Name, [Name]) -> Type
---dataDeclToType (dt, vs) = foldl (\a b -> AppT a (VarT b)) (ConT dt) vs
-
-repField :: (Name, [Name]) -> Type -> Q Type
---repField d t | t == dataDeclToType d = conT ''I
-repField d t = conT ''S1 `appT` conT ''NoSelector `appT`
-                 (conT ''Rec0 `appT` return t)
-
-repField' :: (Name, [Name]) -> Name -> (Name, Strict, Type) -> Q Type
---repField' d ns (_, _, t) | t == dataDeclToType d = conT ''I
-repField' (dt, vs) ns (f, _, t) = conT ''S1 `appT` conT (genName [dt, ns, f]) 
-                                    `appT` (conT ''Rec0 `appT` return t)
--- Note: we should generate Par0 too, at some point
-
-
-mkFrom :: Name -> Int -> Int -> Name -> Q [Q Clause]
-mkFrom ns m i n =
-    do
-      -- runIO $ putStrLn $ "processing " ++ show n
-      let wrapE e = lrE m i e
-      i <- reify n
-      let b = case i of
-                TyConI (DataD _ dt vs cs _) ->
-                  zipWith (fromCon wrapE ns (dt, map tyVarBndrToName vs)
-                    (length cs)) [0..] cs
-                TyConI (NewtypeD _ dt vs c _) ->
-                  [fromCon wrapE ns (dt, map tyVarBndrToName vs) 1 0 c]
-                TyConI (TySynD t _ _) -> error "type synonym?" 
-                  -- [clause [varP (field 0)] (normalB (wrapE $ conE 'K1 `appE` varE (field 0))) []]
-                _ -> error "unknown construct"
-      return b
-
-mkTo :: Name -> Int -> Int -> Name -> Q [Q Clause]
-mkTo ns m i n =
-    do
-      -- runIO $ putStrLn $ "processing " ++ show n
-      let wrapP p = lrP m i p
-      i <- reify n
-      let b = case i of
-                TyConI (DataD _ dt vs cs _) ->
-                  zipWith (toCon wrapP ns (dt, map tyVarBndrToName vs)
-                    (length cs)) [0..] cs
-                TyConI (NewtypeD _ dt vs c _) ->
-                  [toCon wrapP ns (dt, map tyVarBndrToName vs) 1 0 c]
-                TyConI (TySynD t _ _) -> error "type synonym?" 
-                  -- [clause [wrapP $ conP 'K1 [varP (field 0)]] (normalB $ varE (field 0)) []]
-                _ -> error "unknown construct" 
-      return b
-
-fromCon :: (Q Exp -> Q Exp) -> Name -> (Name, [Name]) -> Int -> Int -> Con -> Q Clause
-fromCon wrap ns (dt, vs) m i (NormalC cn []) =
-  clause
-    [conP cn []]
-    (normalB $ appE (conE 'M1) $ wrap $ lrE m i $ appE (conE 'M1) $ 
-      conE 'M1 `appE` (conE 'U1)) []
-fromCon wrap ns (dt, vs) m i (NormalC cn fs) =
-  -- runIO (putStrLn ("constructor " ++ show ix)) >>
-  clause
-    [conP cn (map (varP . field) [0..length fs - 1])]
-    (normalB $ appE (conE 'M1) $ wrap $ lrE m i $ conE 'M1 `appE` 
-      foldr1 prod (zipWith (fromField (dt, vs)) [0..] (map snd fs))) []
-  where prod x y = conE '(:*:) `appE` x `appE` y
-fromCon wrap ns (dt, vs) m i r@(RecC cn []) =
-  clause
-    [conP cn []]
-    (normalB $ appE (conE 'M1) $ wrap $ lrE m i $ conE 'M1 `appE` (conE 'U1)) []
-fromCon wrap ns (dt, vs) m i r@(RecC cn fs) =
-  clause
-    [conP cn (map (varP . field) [0..length fs - 1])]
-    (normalB $ appE (conE 'M1) $ wrap $ lrE m i $ conE 'M1 `appE` 
-      foldr1 prod (zipWith (fromField (dt, vs)) [0..] (map trd fs))) []
-  where prod x y = conE '(:*:) `appE` x `appE` y
-fromCon wrap ns (dt, vs) m i (InfixC t1 cn t2) =
-  fromCon wrap ns (dt, vs) m i (NormalC cn [t1,t2])
-
-fromField :: (Name, [Name]) -> Int -> Type -> Q Exp
---fromField (dt, vs) nr t | t == dataDeclToType (dt, vs) = conE 'I `appE` varE (field nr)
-fromField (dt, vs) nr t = conE 'M1 `appE` (conE 'K1 `appE` varE (field nr))
-
-toCon :: (Q Pat -> Q Pat) -> Name -> (Name, [Name]) -> Int -> Int -> Con -> Q Clause
-toCon wrap ns (dt, vs) m i (NormalC cn []) =
-    clause
-      [wrap $ conP 'M1 [lrP m i $ conP 'M1 [conP 'M1 [conP 'U1 []]]]]
-      (normalB $ conE cn) []
-toCon wrap ns (dt, vs) m i (NormalC cn fs) =
-    -- runIO (putStrLn ("constructor " ++ show ix)) >>
-    clause
-      [wrap $ conP 'M1 [lrP m i $ conP 'M1
-        [foldr1 prod (zipWith (toField (dt, vs)) [0..] (map snd fs))]]]
-      (normalB $ foldl appE (conE cn) (map (varE . field) [0..length fs - 1])) []
-  where prod x y = conP '(:*:) [x,y]
-toCon wrap ns (dt, vs) m i r@(RecC cn []) =
-    clause
-      [wrap $ conP 'M1 [lrP m i $ conP 'M1 [conP 'U1 []]]]
-      (normalB $ conE cn) []
-toCon wrap ns (dt, vs) m i r@(RecC cn fs) =
-    clause
-      [wrap $ conP 'M1 [lrP m i $ conP 'M1
-        [foldr1 prod (zipWith (toField (dt, vs)) [0..] (map trd fs))]]]
-      (normalB $ foldl appE (conE cn) (map (varE . field) [0..length fs - 1])) []
-  where prod x y = conP '(:*:) [x,y]
-toCon wrap ns (dt, vs) m i (InfixC t1 cn t2) =
-  toCon wrap ns (dt, vs) m i (NormalC cn [t1,t2])
-
-toField :: (Name, [Name]) -> Int -> Type -> Q Pat
---toField (dt, vs) nr t | t == dataDeclToType (dt, vs) = conP 'I [varP (field nr)]
-toField (dt, vs) nr t = conP 'M1 [conP 'K1 [varP (field nr)]]
-
-
-field :: Int -> Name
-field n = mkName $ "f" ++ show n
-
-lrP :: Int -> Int -> (Q Pat -> Q Pat)
-lrP 1 0 p = p
-lrP m 0 p = conP 'L1 [p]
-lrP m i p = conP 'R1 [lrP (m-1) (i-1) p]
-
-lrE :: Int -> Int -> (Q Exp -> Q Exp)
-lrE 1 0 e = e
-lrE m 0 e = conE 'L1 `appE` e
-lrE m i e = conE 'R1 `appE` lrE (m-1) (i-1) e
-
-trd (_,_,c) = c
-
--- | Variant of foldr1 which returns a special element for empty lists
-foldr1' f x [] = x
-foldr1' _ _ [x] = x
-foldr1' f x (h:t) = f h (foldr1' f x t)
+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE ViewPatterns #-}++{- |+Module      :  Generics.Deriving.TH+Copyright   :  (c) 2008--2009 Universiteit Utrecht+License     :  BSD3++Maintainer  :  generics@haskell.org+Stability   :  experimental+Portability :  non-portable++This module contains Template Haskell code that can be used to+automatically generate the boilerplate code for the generic deriving+library.++To use these functions, pass the name of a data type as an argument:++@+&#123;-&#35; LANGUAGE TemplateHaskell &#35;-&#125;++data Example a = Example Int Char a+$('deriveAll0'     ''Example) -- Derives Generic instance+$('deriveAll1'     ''Example) -- Derives Generic1 instance+$('deriveAll0And1' ''Example) -- Derives Generic and Generic1 instances+@++On GHC 7.4 or later, this code can also be used with data families. To derive+for a data family instance, pass the name of one of the instance's constructors:++@+&#123;-&#35; LANGUAGE FlexibleInstances, TemplateHaskell, TypeFamilies &#35;-&#125;++data family Family a b+newtype instance Family Char x = FamilyChar Char+data    instance Family Bool x = FamilyTrue | FamilyFalse++$('deriveAll0' 'FamilyChar) -- instance Generic (Family Char b) where ...+$('deriveAll1' 'FamilyTrue) -- instance Generic1 (Family Bool) where ...+-- Alternatively, one could type $(deriveAll1 'FamilyFalse)+@+-}++-- Adapted from Generics.Regular.TH+module Generics.Deriving.TH (+      -- * @derive@- functions+      deriveMeta+    , deriveData+    , deriveConstructors+    , deriveSelectors++    , deriveAll+    , deriveAll0+    , deriveAll1+    , deriveAll0And1+    , deriveRepresentable0+    , deriveRepresentable1+    , deriveRep0+    , deriveRep1++     -- * @make@- functions+     -- $make+    , makeRep0Inline+    , makeRep0+    , makeRep0FromType+    , makeFrom+    , makeFrom0+    , makeTo+    , makeTo0+    , makeRep1Inline+    , makeRep1+    , makeRep1FromType+    , makeFrom1+    , makeTo1++     -- * Options+     -- $options+     -- ** Option types+    , Options(..)+    , defaultOptions+    , RepOptions(..)+    , defaultRepOptions+    , KindSigOptions+    , defaultKindSigOptions+    , EmptyCaseOptions+    , defaultEmptyCaseOptions++    -- ** Functions with optional arguments+    , deriveAll0Options+    , deriveAll1Options+    , deriveAll0And1Options+    , deriveRepresentable0Options+    , deriveRepresentable1Options+    , deriveRep0Options+    , deriveRep1Options++    , makeFrom0Options+    , makeTo0Options+    , makeFrom1Options+    , makeTo1Options+  ) where++import           Control.Monad ((>=>), unless, when)++import qualified Data.Map as Map (empty, fromList)++import           Generics.Deriving.TH.Internal+import           Generics.Deriving.TH.Post4_9++import           Language.Haskell.TH.Datatype+import           Language.Haskell.TH.Datatype.TyVarBndr+import           Language.Haskell.TH.Lib+import           Language.Haskell.TH++{- $options+'Options' gives you a way to further tweak derived 'Generic' and 'Generic1' instances:++*   'RepOptions': By default, all derived 'Rep' and 'Rep1' type instances emit the code+    directly (the 'InlineRep' option). One can also choose to emit a separate type+    synonym for the 'Rep' type (this is the functionality of 'deriveRep0' and+    'deriveRep1') and define a 'Rep' instance in terms of that type synonym (the+    'TypeSynonymRep' option).++*   'EmptyCaseOptions': By default, all derived instances for empty data types+    (i.e., data types with no constructors) use 'error' in @from(1)@/@to(1)@.+    For instance, @data Empty@ would have this derived 'Generic' instance:++    @+    instance Generic Empty where+      type Rep Empty = D1 ('MetaData ...) V1+      from _ = M1 (error "No generic representation for empty datatype Empty")+      to (M1 _) = error "No generic representation for empty datatype Empty"+    @++    This matches the behavior of GHC up until 8.4, when derived @Generic(1)@+    instances began to use the @EmptyCase@ extension. In GHC 8.4, the derived+    'Generic' instance for @Empty@ would instead be:++    @+    instance Generic Empty where+      type Rep Empty = D1 ('MetaData ...) V1+      from x = M1 (case x of {})+      to (M1 x) = case x of {}+    @++    This is a slightly better encoding since, for example, any divergent+    computations passed to 'from' will actually diverge (as opposed to before,+    where the result would always be a call to 'error'). On the other hand, using+    this encoding in @generic-deriving@ has one large drawback: it requires+    enabling @EmptyCase@, an extension which was only introduced in GHC 7.8+    (and only received reliable pattern-match coverage checking in 8.2).++    The 'EmptyCaseOptions' field controls whether code should be emitted that+    uses @EmptyCase@ (i.e., 'EmptyCaseOptions' set to 'True') or not ('False').+    The default value is 'False'. Note that even if set to 'True', this option+    has no effect on GHCs before 7.8, as @EmptyCase@ did not exist then.++*   'KindSigOptions': By default, all derived instances will use explicit kind+    signatures (when the 'KindSigOptions' is 'True'). You might wish to set the+    'KindSigOptions' to 'False' if you want a 'Generic'/'Generic1' instance at+    a particular kind that GHC will infer correctly, but the functions in this+    module won't guess correctly. You probably won't ever need this option+    unless you are a power user.+-}++-- | Additional options for configuring derived 'Generic'/'Generic1' instances+-- using Template Haskell.+data Options = Options+  { repOptions       :: RepOptions+  , kindSigOptions   :: KindSigOptions+  , emptyCaseOptions :: EmptyCaseOptions+  } deriving (Eq, Ord, Read, Show)++-- | Sensible default 'Options'.+defaultOptions :: Options+defaultOptions = Options+  { repOptions       = defaultRepOptions+  , kindSigOptions   = defaultKindSigOptions+  , emptyCaseOptions = defaultEmptyCaseOptions+  }++-- | Configures whether 'Rep'/'Rep1' type instances should be defined inline in a+-- derived 'Generic'/'Generic1' instance ('InlineRep') or defined in terms of a+-- type synonym ('TypeSynonymRep').+data RepOptions = InlineRep+                | TypeSynonymRep+  deriving (Eq, Ord, Read, Show)++-- | 'InlineRep', a sensible default 'RepOptions'.+defaultRepOptions :: RepOptions+defaultRepOptions = InlineRep++-- | 'True' if explicit kind signatures should be used in derived+-- 'Generic'/'Generic1' instances, 'False' otherwise.+type KindSigOptions = Bool++-- | 'True', a sensible default 'KindSigOptions'.+defaultKindSigOptions :: KindSigOptions+defaultKindSigOptions = True++-- | 'True' if generated code for empty data types should use the @EmptyCase@+-- extension, 'False' otherwise. This has no effect on GHCs before 7.8, since+-- @EmptyCase@ is only available in 7.8 or later.+type EmptyCaseOptions = Bool++-- | Sensible default 'EmptyCaseOptions'.+defaultEmptyCaseOptions :: EmptyCaseOptions+defaultEmptyCaseOptions = False++-- | A backwards-compatible synonym for 'deriveAll0'.+deriveAll :: Name -> Q [Dec]+deriveAll = deriveAll0++-- | Given the type and the name (as string) for the type to derive,+-- generate the 'Data' instance, the 'Constructor' instances, the 'Selector'+-- instances, and the 'Representable0' instance.+deriveAll0 :: Name -> Q [Dec]+deriveAll0 = deriveAll0Options defaultOptions++-- | Like 'deriveAll0', but takes an 'Options' argument.+deriveAll0Options :: Options -> Name -> Q [Dec]+deriveAll0Options = deriveAllCommon True False++-- | Given the type and the name (as string) for the type to derive,+-- generate the 'Data' instance, the 'Constructor' instances, the 'Selector'+-- instances, and the 'Representable1' instance.+deriveAll1 :: Name -> Q [Dec]+deriveAll1 = deriveAll1Options defaultOptions++-- | Like 'deriveAll1', but takes an 'Options' argument.+deriveAll1Options :: Options -> Name -> Q [Dec]+deriveAll1Options = deriveAllCommon False True++-- | Given the type and the name (as string) for the type to derive,+-- generate the 'Data' instance, the 'Constructor' instances, the 'Selector'+-- instances, the 'Representable0' instance, and the 'Representable1' instance.+deriveAll0And1 :: Name -> Q [Dec]+deriveAll0And1 = deriveAll0And1Options defaultOptions++-- | Like 'deriveAll0And1', but takes an 'Options' argument.+deriveAll0And1Options :: Options -> Name -> Q [Dec]+deriveAll0And1Options = deriveAllCommon True True++deriveAllCommon :: Bool -> Bool -> Options -> Name -> Q [Dec]+deriveAllCommon generic generic1 opts n = do+    a <- deriveMeta n+    b <- if generic+            then deriveRepresentableCommon Generic opts n+            else return []+    c <- if generic1+            then deriveRepresentableCommon Generic1 opts n+            else return []+    return (a ++ b ++ c)++-- | Given the type and the name (as string) for the Representable0 type+-- synonym to derive, generate the 'Representable0' instance.+deriveRepresentable0 :: Name -> Q [Dec]+deriveRepresentable0 = deriveRepresentable0Options defaultOptions++-- | Like 'deriveRepresentable0', but takes an 'Options' argument.+deriveRepresentable0Options :: Options -> Name -> Q [Dec]+deriveRepresentable0Options = deriveRepresentableCommon Generic++-- | Given the type and the name (as string) for the Representable1 type+-- synonym to derive, generate the 'Representable1' instance.+deriveRepresentable1 :: Name -> Q [Dec]+deriveRepresentable1 = deriveRepresentable1Options defaultOptions++-- | Like 'deriveRepresentable1', but takes an 'Options' argument.+deriveRepresentable1Options :: Options -> Name -> Q [Dec]+deriveRepresentable1Options = deriveRepresentableCommon Generic1++deriveRepresentableCommon :: GenericClass -> Options -> Name -> Q [Dec]+deriveRepresentableCommon gClass opts n = do+    rep  <- if repOptions opts == InlineRep+               then return []+               else deriveRepCommon gClass (kindSigOptions opts) n+    inst <- deriveInst gClass opts n+    return (rep ++ inst)++-- | Derive only the 'Rep0' type synonym. Not needed if 'deriveRepresentable0'+-- is used.+deriveRep0 :: Name -> Q [Dec]+deriveRep0 = deriveRep0Options defaultKindSigOptions++-- | Like 'deriveRep0', but takes an 'KindSigOptions' argument.+deriveRep0Options :: KindSigOptions -> Name -> Q [Dec]+deriveRep0Options = deriveRepCommon Generic++-- | Derive only the 'Rep1' type synonym. Not needed if 'deriveRepresentable1'+-- is used.+deriveRep1 :: Name -> Q [Dec]+deriveRep1 = deriveRep1Options defaultKindSigOptions++-- | Like 'deriveRep1', but takes an 'KindSigOptions' argument.+deriveRep1Options :: KindSigOptions -> Name -> Q [Dec]+deriveRep1Options = deriveRepCommon Generic1++deriveRepCommon :: GenericClass -> KindSigOptions -> Name -> Q [Dec]+deriveRepCommon gClass useKindSigs n = do+  i <- reifyDataInfo n+  let (name, instTys, cons, dv) = either error id i+      gt = mkGenericTvbs gClass instTys+  -- See Note [Forcing buildTypeInstance]+  !_ <- buildTypeInstance gClass useKindSigs name instTys++  -- See Note [Kind signatures in derived instances]+  let tySynVars  = genericInitTvbs gt+      tySynVars' = if useKindSigs+                      then tySynVars+                      else map unKindedTV tySynVars+  fmap (:[]) $ tySynD (genRepName gClass dv name)+                      (changeTVFlags bndrReq tySynVars')+                      (repType gt dv name Map.empty cons)++deriveInst :: GenericClass -> Options -> Name -> Q [Dec]+deriveInst Generic  = deriveInstCommon genericTypeName  repTypeName  Generic  fromValName  toValName+deriveInst Generic1 = deriveInstCommon generic1TypeName rep1TypeName Generic1 from1ValName to1ValName++deriveInstCommon :: Name+                 -> Name+                 -> GenericClass+                 -> Name+                 -> Name+                 -> Options+                 -> Name+                 -> Q [Dec]+deriveInstCommon genericName repName gClass fromName toName opts n = do+  i <- reifyDataInfo n+  let (name, instTys, cons, dv) = either error id i+      gt = mkGenericTvbs gClass instTys+      useKindSigs = kindSigOptions opts+  -- See Note [Forcing buildTypeInstance]+  !(origTy, origKind) <- buildTypeInstance gClass useKindSigs name instTys+  tyInsRHS <- if repOptions opts == InlineRep+                 then repType gt dv name Map.empty cons+                 else makeRepTySynApp gClass dv name origTy++  let origSigTy = if useKindSigs+                     then SigT origTy origKind+                     else origTy+  tyIns <- tySynInstDCompat repName Nothing [return origSigTy] (return tyInsRHS)+  let ecOptions = emptyCaseOptions opts+      mkBody maker = [clause []+                             (normalB $+                              mkCaseExp $+                              maker gt ecOptions name cons)+                             []]+      fcs = mkBody mkFrom+      tcs = mkBody mkTo++      inline_pragmas+        | inlining_useful cons+        = map (\fun_name ->+                pragInlD fun_name+                         Inline FunLike (FromPhase 1)+              ) [fromName, toName]+        | otherwise+        = []++  fmap (:[]) $+    instanceD (cxt []) (conT genericName `appT` return origSigTy)+                       (inline_pragmas ++ [return tyIns, funD fromName fcs, funD toName tcs])+  where+    -- Adapted from inlining_useful in GHC.Tc.Deriv.Generics.mkBindsRep in the+    -- GHC source code:+    --+    -- https://gitlab.haskell.org/ghc/ghc/-/blob/80729d96e47c99dc38e83612dfcfe01cf565eac0/compiler/GHC/Tc/Deriv/Generics.hs#L368-386+    inlining_useful cons+      | ncons <= 1  = True+      | ncons <= 4  = max_fields <= 5+      | ncons <= 8  = max_fields <= 2+      | ncons <= 16 = max_fields <= 1+      | ncons <= 24 = max_fields == 0+      | otherwise   = False+      where+        ncons      = length cons+        max_fields = maximum $ map (length . constructorFields) cons++{- $make++There are some data types for which the Template Haskell deriver functions in+this module are not sophisticated enough to infer the correct 'Generic' or+'Generic1' instances. As an example, consider this data type:++@+newtype Fix f a = Fix (f (Fix f a))+@++A proper 'Generic1' instance would look like this:++@+instance Functor f => Generic1 (Fix f) where ...+@++Unfortunately, 'deriveRepresentable1' cannot infer the @Functor f@ constraint.+One can still define a 'Generic1' instance for @Fix@, however, by using the+functions in this module that are prefixed with @make@-. For example:++@+$('deriveMeta' ''Fix)+$('deriveRep1' ''Fix)+instance Functor f => Generic1 (Fix f) where+  type Rep1 (Fix f) = $('makeRep1Inline' ''Fix [t| Fix f |])+  from1 = $('makeFrom1' ''Fix)+  to1   = $('makeTo1'   ''Fix)+@++Note that due to the lack of type-level lambdas in Haskell, one must manually+apply @'makeRep1Inline' ''Fix@ to the type @Fix f@.++Be aware that there is a bug on GHC 7.0, 7.2, and 7.4 which might prevent you from+using 'makeRep0Inline' and 'makeRep1Inline'. In the @Fix@ example above, you+would experience the following error:++@+    Kinded thing `f' used as a type+    In the Template Haskell quotation [t| Fix f |]+@++Then a workaround is to use 'makeRep1' instead, which requires you to:++1. Invoke 'deriveRep1' beforehand++2. Pass as arguments the type variables that occur in the instance, in order+   from left to right, topologically sorted, excluding duplicates. (Normally,+   'makeRep1Inline' would figure this out for you.)++Using the above example:++@+$('deriveMeta' ''Fix)+$('deriveRep1' ''Fix)+instance Functor f => Generic1 (Fix f) where+  type Rep1 (Fix f) = $('makeRep1' ''Fix) f+  from1 = $('makeFrom1' ''Fix)+  to1   = $('makeTo1'   ''Fix)+@++On GHC 7.4, you might encounter more complicated examples involving data+families. For instance:++@+data family Fix a b c d+newtype instance Fix b (f c) (g b) a = Fix (f (Fix b (f c) (g b) a))++$('deriveMeta' ''Fix)+$('deriveRep1' ''Fix)+instance Functor f => Generic1 (Fix b (f c) (g b)) where+  type Rep1 (Fix b (f c) (g b)) = $('makeRep1' 'Fix) b f c g+  from1 = $('makeFrom1' 'Fix)+  to1   = $('makeTo1'   'Fix)+@++Note that you don't pass @b@ twice, only once.+-}++-- | Generates the full 'Rep' type inline. Since this type can be quite+-- large, it is recommended you only use this to define 'Rep', e.g.,+--+-- @+-- type Rep (Foo (a :: k) b) = $('makeRep0Inline' ''Foo [t| Foo (a :: k) b |])+-- @+--+-- You can then simply refer to @Rep (Foo a b)@ elsewhere.+--+-- Note that the type passed as an argument to 'makeRep0Inline' must match the+-- type argument of 'Rep' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep0Inline' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+makeRep0Inline :: Name -> Q Type -> Q Type+makeRep0Inline n = makeRepCommon Generic InlineRep n . Just++-- | Generates the full 'Rep1' type inline. Since this type can be quite+-- large, it is recommended you only use this to define 'Rep1', e.g.,+--+-- @+-- type Rep1 (Foo (a :: k)) = $('makeRep0Inline' ''Foo [t| Foo (a :: k) |])+-- @+--+-- You can then simply refer to @Rep1 (Foo a)@ elsewhere.+--+-- Note that the type passed as an argument to 'makeRep1Inline' must match the+-- type argument of 'Rep1' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep1Inline' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+makeRep1Inline :: Name -> Q Type -> Q Type+makeRep1Inline n = makeRepCommon Generic1 InlineRep n . Just++-- | Generates the 'Rep' type synonym constructor (as opposed to 'deriveRep0',+-- which generates the type synonym declaration). After splicing it into+-- Haskell source, it expects types as arguments. For example:+--+-- @+-- type Rep (Foo a b) = $('makeRep0' ''Foo) a b+-- @+--+-- The use of 'makeRep0' is generally discouraged, as it can sometimes be+-- difficult to predict the order in which you are expected to pass type+-- variables. As a result, 'makeRep0Inline' is recommended instead. However,+-- 'makeRep0Inline' is not usable on GHC 7.0, 7.2, or 7.4 due to a GHC bug,+-- so 'makeRep0' still exists for GHC 7.0, 7.2, and 7.4 users.+makeRep0 :: Name -> Q Type+makeRep0 n = makeRepCommon Generic TypeSynonymRep n Nothing++-- | Generates the 'Rep1' type synonym constructor (as opposed to 'deriveRep1',+-- which generates the type synonym declaration). After splicing it into+-- Haskell source, it expects types as arguments. For example:+--+-- @+-- type Rep1 (Foo a) = $('makeRep1' ''Foo) a+-- @+--+-- The use of 'makeRep1' is generally discouraged, as it can sometimes be+-- difficult to predict the order in which you are expected to pass type+-- variables. As a result, 'makeRep1Inline' is recommended instead. However,+-- 'makeRep1Inline' is not usable on GHC 7.0, 7.2, or 7.4 due to a GHC bug,+-- so 'makeRep1' still exists for GHC 7.0, 7.2, and 7.4 users.+makeRep1 :: Name -> Q Type+makeRep1 n = makeRepCommon Generic1 TypeSynonymRep n Nothing++-- | Generates the 'Rep' type synonym constructor (as opposed to 'deriveRep0',+-- which generates the type synonym declaration) applied to its type arguments.+-- Unlike 'makeRep0', this also takes a quoted 'Type' as an argument, e.g.,+--+-- @+-- type Rep (Foo (a :: k) b) = $('makeRep0FromType' ''Foo [t| Foo (a :: k) b |])+-- @+--+-- Note that the type passed as an argument to 'makeRep0FromType' must match the+-- type argument of 'Rep' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep0FromType' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+--+-- The use of 'makeRep0FromType' is generally discouraged, since 'makeRep0Inline'+-- does exactly the same thing but without having to go through an intermediate+-- type synonym, and as a result, 'makeRep0Inline' tends to be less buggy.+makeRep0FromType :: Name -> Q Type -> Q Type+makeRep0FromType n = makeRepCommon Generic TypeSynonymRep n . Just++-- | Generates the 'Rep1' type synonym constructor (as opposed to 'deriveRep1',+-- which generates the type synonym declaration) applied to its type arguments.+-- Unlike 'makeRep1', this also takes a quoted 'Type' as an argument, e.g.,+--+-- @+-- type Rep1 (Foo (a :: k)) = $('makeRep1FromType' ''Foo [t| Foo (a :: k) |])+-- @+--+-- Note that the type passed as an argument to 'makeRep1FromType' must match the+-- type argument of 'Rep' exactly, even up to including the explicit kind+-- signature on @a@. This is due to a limitation of Template Haskell—without+-- the kind signature, 'makeRep1FromType' has no way of figuring out the kind of+-- @a@, and the generated type might be completely wrong as a result!+--+-- The use of 'makeRep1FromType' is generally discouraged, since 'makeRep1Inline'+-- does exactly the same thing but without having to go through an intermediate+-- type synonym, and as a result, 'makeRep1Inline' tends to be less buggy.+makeRep1FromType :: Name -> Q Type -> Q Type+makeRep1FromType n = makeRepCommon Generic1 TypeSynonymRep n . Just++makeRepCommon :: GenericClass+              -> RepOptions+              -> Name+              -> Maybe (Q Type)+              -> Q Type+makeRepCommon gClass repOpts n mbQTy = do+  i <- reifyDataInfo n+  let (name, instTys, cons, dv) = either error id i+      gt = mkGenericTvbs gClass instTys+  -- See Note [Forcing buildTypeInstance]+  !_ <- buildTypeInstance gClass False name instTys++  case (mbQTy, repOpts) of+       (Just qTy, TypeSynonymRep) -> qTy >>= makeRepTySynApp gClass dv name+       (Just qTy, InlineRep)      -> qTy >>= makeRepInline gt dv name cons+       (Nothing,  TypeSynonymRep) -> conT $ genRepName gClass dv name+       (Nothing,  InlineRep)      -> fail "makeRepCommon"++makeRepInline :: GenericTvbs+              -> DatatypeVariant_+              -> Name+              -> [ConstructorInfo]+              -> Type+              -> Q Type+makeRepInline gt dv name cons ty = do+  let instVars = freeVariablesWellScoped [ty]+      tySynVars = genericInitTvbs gt++      typeSubst :: TypeSubst+      typeSubst = Map.fromList $+        zip (map tvName tySynVars)+            (map (VarT . tvName) instVars)++  repType gt dv name typeSubst cons++makeRepTySynApp :: GenericClass -> DatatypeVariant_ -> Name+                -> Type -> Q Type+makeRepTySynApp gClass dv name ty =+  -- Here, we figure out the distinct type variables (in order from left-to-right)+  -- of the LHS of the Rep(1) instance. We call unKindedTV because the kind+  -- inferencer can figure out the kinds perfectly well, so we don't need to+  -- give anything here explicit kind signatures.+  let instTvbs = map unKindedTV $ freeVariablesWellScoped [ty]+  in return $ applyTyToTvbs (genRepName gClass dv name) instTvbs++-- | A backwards-compatible synonym for 'makeFrom0'.+makeFrom :: Name -> Q Exp+makeFrom = makeFrom0++-- | Generates a lambda expression which behaves like 'from'.+makeFrom0 :: Name -> Q Exp+makeFrom0 = makeFrom0Options defaultEmptyCaseOptions++-- | Like 'makeFrom0Options', but takes an 'EmptyCaseOptions' argument.+makeFrom0Options :: EmptyCaseOptions -> Name -> Q Exp+makeFrom0Options = makeFunCommon mkFrom Generic++-- | A backwards-compatible synonym for 'makeTo0'.+makeTo :: Name -> Q Exp+makeTo = makeTo0++-- | Generates a lambda expression which behaves like 'to'.+makeTo0 :: Name -> Q Exp+makeTo0 = makeTo0Options defaultEmptyCaseOptions++-- | Like 'makeTo0Options', but takes an 'EmptyCaseOptions' argument.+makeTo0Options :: EmptyCaseOptions -> Name -> Q Exp+makeTo0Options = makeFunCommon mkTo Generic++-- | Generates a lambda expression which behaves like 'from1'.+makeFrom1 :: Name -> Q Exp+makeFrom1 = makeFrom1Options defaultEmptyCaseOptions++-- | Like 'makeFrom1Options', but takes an 'EmptyCaseOptions' argument.+makeFrom1Options :: EmptyCaseOptions -> Name -> Q Exp+makeFrom1Options = makeFunCommon mkFrom Generic1++-- | Generates a lambda expression which behaves like 'to1'.+makeTo1 :: Name -> Q Exp+makeTo1 = makeTo1Options defaultEmptyCaseOptions++-- | Like 'makeTo1Options', but takes an 'EmptyCaseOptions' argument.+makeTo1Options :: EmptyCaseOptions -> Name -> Q Exp+makeTo1Options = makeFunCommon mkTo Generic1++makeFunCommon+  :: (GenericTvbs -> EmptyCaseOptions -> Name -> [ConstructorInfo] -> Q Match)+  -> GenericClass -> EmptyCaseOptions -> Name -> Q Exp+makeFunCommon maker gClass ecOptions n = do+  i <- reifyDataInfo n+  let (name, instTys, cons, _) = either error id i+      gt = mkGenericTvbs gClass instTys+  -- See Note [Forcing buildTypeInstance]+  buildTypeInstance gClass False name instTys+    `seq` mkCaseExp (maker gt ecOptions name cons)++genRepName :: GenericClass -> DatatypeVariant_+           -> Name -> Name+genRepName gClass dv n+  = mkName+  . showsDatatypeVariant dv+  . (("Rep" ++ show (fromEnum gClass)) ++)+  . ((showNameQual n ++ "_") ++)+  . sanitizeName+  $ nameBase n++repType :: GenericTvbs+        -> DatatypeVariant_+        -> Name+        -> TypeSubst+        -> [ConstructorInfo]+        -> Q Type+repType gt dv dt typeSubst cs =+    conT d1TypeName `appT` mkMetaDataType dv dt `appT`+      foldBal sum' (conT v1TypeName) (map (repCon gt dv dt typeSubst) cs)+  where+    sum' :: Q Type -> Q Type -> Q Type+    sum' a b = conT sumTypeName `appT` a `appT` b++repCon :: GenericTvbs+       -> DatatypeVariant_+       -> Name+       -> TypeSubst+       -> ConstructorInfo+       -> Q Type+repCon gt dv dt typeSubst+  (ConstructorInfo { constructorName       = n+                   , constructorVars       = vars+                   , constructorContext    = ctxt+                   , constructorStrictness = bangs+                   , constructorFields     = ts+                   , constructorVariant    = cv+                   }) = do+  checkExistentialContext n vars ctxt+  let mbSelNames = case cv of+                     NormalConstructor          -> Nothing+                     InfixConstructor           -> Nothing+                     RecordConstructor selNames -> Just selNames+      isRecord   = case cv of+                     NormalConstructor   -> False+                     InfixConstructor    -> False+                     RecordConstructor _ -> True+      isInfix    = case cv of+                     NormalConstructor   -> False+                     InfixConstructor    -> True+                     RecordConstructor _ -> False+  ssis <- reifySelStrictInfo n bangs+  repConWith gt dv dt n typeSubst mbSelNames ssis ts isRecord isInfix++repConWith :: GenericTvbs+           -> DatatypeVariant_+           -> Name+           -> Name+           -> TypeSubst+           -> Maybe [Name]+           -> [SelStrictInfo]+           -> [Type]+           -> Bool+           -> Bool+           -> Q Type+repConWith gt dv dt n typeSubst mbSelNames ssis ts isRecord isInfix = do+    let structureType :: Q Type+        structureType = foldBal prodT (conT u1TypeName) f++        f :: [Q Type]+        f = case mbSelNames of+                 Just selNames -> zipWith3 (repField gt dv dt n typeSubst . Just)+                                           selNames ssis ts+                 Nothing       -> zipWith  (repField gt dv dt n typeSubst Nothing)+                                           ssis ts++    conT c1TypeName+      `appT` mkMetaConsType dv dt n isRecord isInfix+      `appT` structureType++prodT :: Q Type -> Q Type -> Q Type+prodT a b = conT productTypeName `appT` a `appT` b++repField :: GenericTvbs+         -> DatatypeVariant_+         -> Name+         -> Name+         -> TypeSubst+         -> Maybe Name+         -> SelStrictInfo+         -> Type+         -> Q Type+repField gt dv dt ns typeSubst mbF ssi t =+           conT s1TypeName+    `appT` mkMetaSelType dv dt ns mbF ssi+    `appT` (repFieldArg gt =<< resolveTypeSynonyms t'')+  where+    -- See Note [Generic1 is polykinded in base-4.10]+    t', t'' :: Type+    t' = case gt of+              Gen1{gen1LastTvbKindVar = Just _kvName} ->+#if MIN_VERSION_base(4,10,0)+                t+#else+                substNameWithKind _kvName starK t+#endif+              _ -> t+    t'' = applySubstitution typeSubst t'++repFieldArg :: GenericTvbs -> Type -> Q Type+repFieldArg Gen0{} t = boxT t+repFieldArg (Gen1{gen1LastTvbName = name}) (dustOff -> t0) =+    go t0 >>= \res -> case res of+      NoPar -> boxT t0+      ArgRes _ r -> return r+  where+    -- | Returns NoPar if the parameter doesn't appear.+    -- Expects its argument to have been dusted.+    go :: Type -> Q (ArgRes Type)+    go ForallT{} = rankNError+#if MIN_VERSION_template_haskell(2,16,0)+    go ForallVisT{} = rankNError+#endif+    go (VarT t) | t == name = ArgRes True `fmap` conT par1TypeName+    go (AppT f x) = do+      when (not (f `ground` name)) outOfPlaceTyVarError+      mxr <- go (dustOff x)+      case mxr of+        NoPar -> return NoPar+        ArgRes arg_is_param xr -> do+          itf <- isUnsaturatedType f+          when itf typeFamilyApplicationError+          ArgRes False `fmap`+            if arg_is_param+              then+                conT rec1TypeName `appT` return f+              else+                conT composeTypeName `appT` return f `appT` return xr+    go _ = return NoPar++-- | The result of checking the argument. This NoPar+-- means the parameter wasn't there. The Bool is True+-- if the argument *is* the parameter, and False otherwise.+data ArgRes a = NoPar | ArgRes !Bool a++boxT :: Type -> Q Type+boxT ty = case unboxedRepNames ty of+    Just (boxTyName, _, _) -> conT boxTyName+    Nothing                -> conT rec0TypeName `appT` return ty++mkCaseExp :: Q Match -> Q Exp+mkCaseExp qMatch = do+  val <- newName "val"+  lam1E (varP val) $ caseE (varE val) [qMatch]++mkFrom :: GenericTvbs -> EmptyCaseOptions -> Name+       -> [ConstructorInfo] -> Q Match+mkFrom gt ecOptions dt cs = do+    y <- newName "y"+    match (varP y)+          (normalB $ conE m1DataName `appE` caseE (varE y) cases)+          []+  where+    cases = case cs of+              [] -> errorFrom ecOptions dt+              _  -> zipWith (fromCon gt id (length cs)) [1..] cs++errorFrom :: EmptyCaseOptions -> Name -> [Q Match]+errorFrom useEmptyCase dt+  | useEmptyCase+  = []+  | otherwise+  = [do z <- newName "z"+        match+          (varP z)+          (normalB $+            appE (varE seqValName) (varE z) `appE`+            appE (varE errorValName)+                 (stringE $ "No generic representation for empty datatype "+                          ++ nameBase dt))+          []]++mkTo :: GenericTvbs -> EmptyCaseOptions -> Name+     -> [ConstructorInfo] -> Q Match+mkTo gt ecOptions dt cs = do+    y <- newName "y"+    match (conP m1DataName [varP y])+          (normalB $ caseE (varE y) cases)+          []+  where+    cases = case cs of+              [] -> errorTo ecOptions dt+              _  -> zipWith (toCon gt id (length cs)) [1..] cs++errorTo :: EmptyCaseOptions -> Name -> [Q Match]+errorTo useEmptyCase dt+  | useEmptyCase+  = []+  | otherwise+  = [do z <- newName "z"+        match+          (varP z)+          (normalB $+            appE (varE seqValName) (varE z) `appE`+            appE (varE errorValName)+                 (stringE $ "No values for empty datatype " ++ nameBase dt))+          []]++fromCon :: GenericTvbs -> (Q Exp -> Q Exp) -> Int -> Int+        -> ConstructorInfo -> Q Match+fromCon gt wrap m i+  (ConstructorInfo { constructorName    = cn+                   , constructorVars    = vars+                   , constructorContext = ctxt+                   , constructorFields  = ts+                   }) = do+  checkExistentialContext cn vars ctxt+  fNames <- newNameList "f" $ length ts+  match (conP cn (map varP fNames))+        (normalB $ wrap $ lrE i m $ conE m1DataName `appE`+          foldBal prodE (conE u1DataName) (zipWith (fromField gt) fNames ts)) []++prodE :: Q Exp -> Q Exp -> Q Exp+prodE x y = conE productDataName `appE` x `appE` y++fromField :: GenericTvbs -> Name -> Type -> Q Exp+fromField gt nr t = conE m1DataName `appE` (fromFieldWrap gt nr =<< resolveTypeSynonyms t)++fromFieldWrap :: GenericTvbs -> Name -> Type -> Q Exp+fromFieldWrap _                              _  ForallT{}  = rankNError+fromFieldWrap gt                             nr (SigT t _) = fromFieldWrap gt nr t+fromFieldWrap Gen0{}                         nr t          = conE (boxRepName t) `appE` varE nr+fromFieldWrap (Gen1{gen1LastTvbName = name}) nr t          = wC t name           `appE` varE nr++wC :: Type -> Name -> Q Exp+wC (dustOff -> t0) name =+    go t0 >>= \res -> case res of+      NoPar -> conE $ boxRepName t0+      ArgRes _ r -> return r+  where+    -- | Returns NoPar if the parameter doesn't appear.+    -- Expects its argument to have been dusted.+    go :: Type -> Q (ArgRes Exp)+    go ForallT{} = rankNError+#if MIN_VERSION_template_haskell(2,16,0)+    go ForallVisT{} = rankNError+#endif+    go (VarT t) | t == name = ArgRes True `fmap` conE par1DataName+    go (AppT f x) = do+      when (not (f `ground` name)) outOfPlaceTyVarError+      mxr <- go (dustOff x)+      case mxr of+        NoPar -> return NoPar+        ArgRes arg_is_param xr -> do+          itf <- isUnsaturatedType f+          when itf typeFamilyApplicationError+          ArgRes False `fmap`+            if arg_is_param+              then+                conE rec1DataName+              else+                infixApp (conE comp1DataName) (varE composeValName) (varE fmapValName `appE` return xr)+    go _ = return NoPar++boxRepName :: Type -> Name+boxRepName = maybe k1DataName snd3 . unboxedRepNames++toCon :: GenericTvbs -> (Q Pat -> Q Pat) -> Int -> Int+      -> ConstructorInfo -> Q Match+toCon gt wrap m i+  (ConstructorInfo { constructorName    = cn+                   , constructorVars    = vars+                   , constructorContext = ctxt+                   , constructorFields  = ts+                   }) = do+  checkExistentialContext cn vars ctxt+  fNames <- newNameList "f" $ length ts+  match (wrap $ lrP i m $ conP m1DataName+          [foldBal prod (conP u1DataName []) (zipWith (toField gt) fNames ts)])+        (normalB $ foldl appE (conE cn)+                         (zipWith (\nr -> resolveTypeSynonyms >=> toConUnwC gt nr)+                         fNames ts)) []+  where prod x y = conP productDataName [x,y]++toConUnwC :: GenericTvbs -> Name -> Type -> Q Exp+toConUnwC Gen0{}                         nr _ = varE nr+toConUnwC (Gen1{gen1LastTvbName = name}) nr t = unwC t name `appE` varE nr++toField :: GenericTvbs -> Name -> Type -> Q Pat+toField gt nr t = conP m1DataName [toFieldWrap gt nr t]++toFieldWrap :: GenericTvbs -> Name -> Type -> Q Pat+toFieldWrap Gen0{} nr t = conP (boxRepName t) [varP nr]+toFieldWrap Gen1{} nr _ = varP nr++unwC :: Type -> Name -> Q Exp+unwC (dustOff -> t0) name =+  go t0 >>= \res -> case res of+    NoPar -> varE $ unboxRepName t0+    ArgRes _ r -> return r+  where+    -- | Returns NoPar if the parameter doesn't appear.+    -- Expects its argument to have been dusted.+    go :: Type -> Q (ArgRes Exp)+    go ForallT{} = rankNError+#if MIN_VERSION_template_haskell(2,16,0)+    go ForallVisT{} = rankNError+#endif+    go (VarT t) | t == name = ArgRes True `fmap` varE unPar1ValName+    go (AppT f x) = do+      when (not (f `ground` name)) outOfPlaceTyVarError+      mxr <- go (dustOff x)+      case mxr of+        NoPar -> return NoPar+        ArgRes arg_is_param xr -> do+          itf <- isUnsaturatedType f+          when itf typeFamilyApplicationError+          ArgRes False `fmap`+            if arg_is_param+              then+                varE unRec1ValName+              else+                infixApp (varE fmapValName `appE` return xr)+                         (varE composeValName)+                         (varE unComp1ValName)+    go _ = return NoPar++unboxRepName :: Type -> Name+unboxRepName = maybe unK1ValName trd3 . unboxedRepNames++lrP :: Int -> Int -> (Q Pat -> Q Pat)+lrP i n p+  | n == 0       = fail "lrP: impossible"+  | n == 1       = p+  | i <= div n 2 = conP l1DataName [lrP i     (div n 2) p]+  | otherwise    = conP r1DataName [lrP (i-m) (n-m)     p]+                     where m = div n 2++lrE :: Int -> Int -> (Q Exp -> Q Exp)+lrE i n e+  | n == 0       = fail "lrE: impossible"+  | n == 1       = e+  | i <= div n 2 = conE l1DataName `appE` lrE i     (div n 2) e+  | otherwise    = conE r1DataName `appE` lrE (i-m) (n-m)     e+                     where m = div n 2++unboxedRepNames :: Type -> Maybe (Name, Name, Name)+unboxedRepNames ty+  | ty == ConT addrHashTypeName   = Just (uAddrTypeName,   uAddrDataName,   uAddrHashValName)+  | ty == ConT charHashTypeName   = Just (uCharTypeName,   uCharDataName,   uCharHashValName)+  | ty == ConT doubleHashTypeName = Just (uDoubleTypeName, uDoubleDataName, uDoubleHashValName)+  | ty == ConT floatHashTypeName  = Just (uFloatTypeName,  uFloatDataName,  uFloatHashValName)+  | ty == ConT intHashTypeName    = Just (uIntTypeName,    uIntDataName,    uIntHashValName)+  | ty == ConT wordHashTypeName   = Just (uWordTypeName,   uWordDataName,   uWordHashValName)+  | otherwise                     = Nothing++-- For the given Types, deduces the instance type (and kind) to use for a+-- Generic(1) instance. Coming up with the instance type isn't as simple as+-- dropping the last types, as you need to be wary of kinds being instantiated+-- with *.+-- See Note [Type inference in derived instances]+buildTypeInstance :: GenericClass+                  -- ^ Generic or Generic1+                  -> KindSigOptions+                  -- ^ Whether or not to use explicit kind signatures in the instance type+                  -> Name+                  -- ^ The type constructor or data family name+                  -> [Type]+                  -- ^ The types to instantiate the instance with+                  -> Q (Type, Kind)+buildTypeInstance gClass useKindSigs tyConName varTysOrig = do+    -- Make sure to expand through type/kind synonyms! Otherwise, the+    -- eta-reduction check might get tripped up over type variables in a+    -- synonym that are actually dropped.+    -- (See GHC Trac #11416 for a scenario where this actually happened.)+    varTysExp <- mapM resolveTypeSynonyms varTysOrig++    let remainingLength :: Int+        remainingLength = length varTysOrig - fromEnum gClass++#if !(MIN_VERSION_base(4,10,0))+        droppedTysExp :: [Type]+        droppedTysExp = drop remainingLength varTysExp++        droppedStarKindStati :: [StarKindStatus]+        droppedStarKindStati = map canRealizeKindStar droppedTysExp+#endif++    -- Check that:+    --+    -- 1. There are enough types to drop+    --+    -- 2. If using GHC 8.0 or earlier, all types are either of kind * or kind k+    --    (for some kind variable k). See Note [Generic1 is polykinded in base-4.10].+    --+    -- If either of these checks fail, throw an error.+    when (remainingLength < 0+#if !(MIN_VERSION_base(4,10,0))+           || any (== OtherKind) droppedStarKindStati+#endif+         ) $+      derivingKindError tyConName++        -- Substitute kind * for any dropped kind variables+    let varTysExpSubst :: [Type]+-- See Note [Generic1 is polykinded in base-4.10]+#if MIN_VERSION_base(4,10,0)+        varTysExpSubst = varTysExp+#else+        varTysExpSubst = map (substNamesWithKindStar droppedKindVarNames) varTysExp++        droppedKindVarNames :: [Name]+        droppedKindVarNames = catKindVarNames droppedStarKindStati+#endif++    let remainingTysExpSubst, droppedTysExpSubst :: [Type]+        (remainingTysExpSubst, droppedTysExpSubst) =+          splitAt remainingLength varTysExpSubst++-- See Note [Generic1 is polykinded in base-4.10]+#if !(MIN_VERSION_base(4,10,0))+    -- If any of the dropped types were polykinded, ensure that there are of+    -- kind * after substituting * for the dropped kind variables. If not,+    -- throw an error.+    unless (all hasKindStar droppedTysExpSubst) $+      derivingKindError tyConName+#endif++        -- We now substitute all of the specialized-to-* kind variable names+        -- with *, but in the original types, not the synonym-expanded types. The reason+        -- we do this is a superficial one: we want the derived instance to resemble+        -- the datatype written in source code as closely as possible. For example,+        -- for the following data family instance:+        --+        --   data family Fam a+        --   newtype instance Fam String = Fam String+        --+        -- We'd want to generate the instance:+        --+        --   instance C (Fam String)+        --+        -- Not:+        --+        --   instance C (Fam [Char])+    let varTysOrigSubst :: [Type]+        varTysOrigSubst =+-- See Note [Generic1 is polykinded in base-4.10]+#if MIN_VERSION_base(4,10,0)+          id+#else+          map (substNamesWithKindStar droppedKindVarNames)+#endif+            $ varTysOrig++        remainingTysOrigSubst, droppedTysOrigSubst :: [Type]+        (remainingTysOrigSubst, droppedTysOrigSubst) =+            splitAt remainingLength varTysOrigSubst++        remainingTysOrigSubst' :: [Type]+        -- See Note [Kind signatures in derived instances] for an explanation+        -- of the useKindSigs check.+        remainingTysOrigSubst' =+          if useKindSigs+             then remainingTysOrigSubst+             else map unSigT remainingTysOrigSubst++        instanceType :: Type+        instanceType = applyTyToTys (ConT tyConName) remainingTysOrigSubst'++        -- See Note [Kind signatures in derived instances]+        instanceKind :: Kind+        instanceKind = makeFunKind (map typeKind droppedTysOrigSubst) starK++    -- Ensure the dropped types can be safely eta-reduced. Otherwise,+    -- throw an error.+    unless (canEtaReduce remainingTysExpSubst droppedTysExpSubst) $+      etaReductionError instanceType+    return (instanceType, instanceKind)++{-+Note [Forcing buildTypeInstance]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Sometimes, we don't explicitly need to generate a Generic(1) type instance, but+we force buildTypeInstance nevertheless. This is because it performs some checks+for whether or not the provided datatype can actually have Generic(1) implemented for+it, and produces errors if it can't. Otherwise, laziness would cause these checks+to be skipped entirely, which could result in some indecipherable type errors+down the road.++Note [Kind signatures in derived instances]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++We generally include explicit type signatures in derived instances. One reason for+doing so is that in the case of certain data family instances, not including kind+signatures can result in ambiguity. For example, consider the following two data+family instances that are distinguished by their kinds:++  data family Fam (a :: k)+  data instance Fam (a :: * -> *)+  data instance Fam (a :: *)++If we dropped the kind signature for a in a derived instance for Fam a, then GHC+would have no way of knowing which instance we are talking about.++In addition to using explicit kind signatures in the instance head, we also put+explicit kinds in the associated Rep(1) instance. For example, this data type:++  data S (a :: k) = S k++Will have the following Generic1 instance generated for it:++  instance Generic1 (S :: k -> *) where+    type Rep1 (S :: k -> *) = ... (Rec0 k)++Why do we do this? Imagine what the instance would be without the explicit kind+annotation in the Rep1 instance:++  instance Generic1 S where+    type Rep1 S = ... (Rec0 k)++This is an error, since the variable k is now out-of-scope!++In the rare event that attaching explicit kind annotations does the wrong+thing, there are variants of the TH functions that allow configuring the+KindSigOptions. If KindSigOptions is set to False, then generated instances+will not include explicit kind signatures, leaving it up to GHC's kind+inference machinery to figure out the correct kinds.++Note [Generic1 is polykinded in base-4.10]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Prior to base-4.10, Generic1 :: (* -> *) -> Constraint. This means that if a Generic1+instance is defined for a polykinded data type like so:++  data Proxy k (a :: k) = Proxy++Then k is unified with *, and this has an effect on the generated Generic1 instance:++  instance Generic1 (Proxy *) where ...++We must take great care to ensure that all occurrences of k are substituted with *,+or else the generated instance will be ill kinded.++In base-4.10 and later, Generic1 :: (k -> *) -> Constraint. This means we don't have+to do any of this kind unification trickery anymore! Hooray!+-}
+ src/Generics/Deriving/TH/Internal.hs view
@@ -0,0 +1,830 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE TemplateHaskellQuotes #-}++{- |+Module      :  Generics.Deriving.TH.Internal+Copyright   :  (c) 2008--2009 Universiteit Utrecht+License     :  BSD3++Maintainer  :  generics@haskell.org+Stability   :  experimental+Portability :  non-portable++Template Haskell-related utilities.+-}++module Generics.Deriving.TH.Internal where++import           Control.Monad (unless)++import           Data.Char (isAlphaNum, ord)+import           Data.Foldable (foldr')+import qualified Data.List as List+import qualified Data.Map as Map+import           Data.Map as Map (Map)+import           Data.Maybe (mapMaybe)+import qualified Data.Set as Set+import           Data.Set (Set)++import qualified Generics.Deriving as GD+import           Generics.Deriving hiding+                   ( DecidedStrictness(..), Fixity(Infix)+                   , SourceStrictness(..), SourceUnpackedness(..)+                   , datatypeName+                   )++import           GHC.Exts (Addr#, Char#, Double#, Float#, Int#, Word#)++import           Language.Haskell.TH.Datatype as Datatype+import           Language.Haskell.TH.Datatype.TyVarBndr+import           Language.Haskell.TH.Lib+import           Language.Haskell.TH.Ppr (pprint)+import           Language.Haskell.TH.Syntax++-------------------------------------------------------------------------------+-- Expanding type synonyms+-------------------------------------------------------------------------------++type TypeSubst = Map Name Type++applySubstitutionKind :: Map Name Kind -> Type -> Type+applySubstitutionKind = applySubstitution++substNameWithKind :: Name -> Kind -> Type -> Type+substNameWithKind n k = applySubstitutionKind (Map.singleton n k)++substNamesWithKindStar :: [Name] -> Type -> Type+substNamesWithKindStar ns t = foldr' (flip substNameWithKind starK) t ns++-------------------------------------------------------------------------------+-- StarKindStatus+-------------------------------------------------------------------------------++-- | Whether a type is of kind @*@, a kind variable, or some other kind. The+-- kind variable case is given special treatment solely to support GHC 8.0 and+-- earlier, in which Generic1 was not poly-kinded. In order to support deriving+-- Generic1 instances on these versions of GHC, we must substitute such kinds+-- with @*@ to ensure that the resulting instance is well kinded.+-- See @Note [Generic1 is polykinded in base-4.10]@ in "Generics.Deriving.TH".+data StarKindStatus = KindStar+                    | IsKindVar Name+                    | OtherKind+  deriving Eq++-- | Does a Type have kind * or k (for some kind variable k)?+canRealizeKindStar :: Type -> StarKindStatus+canRealizeKindStar t+  | hasKindStar t = KindStar+  | otherwise = case t of+                     SigT _ (VarT k) -> IsKindVar k+                     _               -> OtherKind++-- | Returns 'Just' the kind variable 'Name' of a 'StarKindStatus' if it exists.+-- Otherwise, returns 'Nothing'.+starKindStatusToName :: StarKindStatus -> Maybe Name+starKindStatusToName (IsKindVar n) = Just n+starKindStatusToName _             = Nothing++-- | Concat together all of the StarKindStatuses that are IsKindVar and extract+-- the kind variables' Names out.+catKindVarNames :: [StarKindStatus] -> [Name]+catKindVarNames = mapMaybe starKindStatusToName++-------------------------------------------------------------------------------+-- Assorted utilities+-------------------------------------------------------------------------------++-- | Returns True if a Type has kind *.+hasKindStar :: Type -> Bool+hasKindStar VarT{}         = True+hasKindStar (SigT _ StarT) = True+hasKindStar _              = False++-- | Converts a VarT or a SigT into Just the corresponding TyVarBndr.+-- Converts other Types to Nothing.+typeToTyVarBndr :: Type -> Maybe TyVarBndrUnit+typeToTyVarBndr (VarT n)          = Just (plainTV n)+typeToTyVarBndr (SigT (VarT n) k) = Just (kindedTV n k)+typeToTyVarBndr _                 = Nothing++-- | If a Type is a SigT, returns its kind signature. Otherwise, return *.+typeKind :: Type -> Kind+typeKind (SigT _ k) = k+typeKind _          = starK++-- | Turns+--+-- @+-- [a, b] c+-- @+--+-- into+--+-- @+-- a -> b -> c+-- @+makeFunType :: [Type] -> Type -> Type+makeFunType argTys resTy = foldr' (AppT . AppT ArrowT) resTy argTys++-- | Turns+--+-- @+-- [k1, k2] k3+-- @+--+-- into+--+-- @+-- k1 -> k2 -> k3+-- @+makeFunKind :: [Kind] -> Kind -> Kind+makeFunKind = makeFunType++-- | Remove any outer `SigT` and `ParensT` constructors, and turn+-- an outermost `InfixT` constructor into plain applications.+dustOff :: Type -> Type+dustOff (SigT ty _) = dustOff ty+dustOff (ParensT ty) = dustOff ty+dustOff (InfixT ty1 n ty2) = ConT n `AppT` ty1 `AppT` ty2+dustOff ty = ty++-- | Checks whether a type is an unsaturated type family+-- application.+isUnsaturatedType :: Type -> Q Bool+isUnsaturatedType = go 0 . dustOff+  where+    -- Expects its argument to be dusted+    go :: Int -> Type -> Q Bool+    go d t = case t of+      ConT tcName -> check d tcName+      AppT f _ -> go (d + 1) (dustOff f)+      _ -> return False++    check :: Int -> Name -> Q Bool+    check d tcName = do+      mbinders <- getTypeFamilyBinders tcName+      return $ case mbinders of+        Just bndrs -> length bndrs > d+        Nothing -> False++-- | Given a name, check if that name is a type family. If+-- so, return a list of its binders.+getTypeFamilyBinders :: Name -> Q (Maybe [TyVarBndrVis])+getTypeFamilyBinders tcName = do+      info <- reify tcName+      return $ case info of+        FamilyI (OpenTypeFamilyD (TypeFamilyHead _ bndrs _ _)) _+          -> Just bndrs+        FamilyI (ClosedTypeFamilyD (TypeFamilyHead _ bndrs _ _) _) _+          -> Just bndrs+        _ -> Nothing++-- | True if the type does not mention the Name+ground :: Type -> Name -> Bool+ground ty name = name `notElem` freeVariables ty++-- | Construct a type via curried application.+applyTyToTys :: Type -> [Type] -> Type+applyTyToTys = List.foldl' AppT++-- | Apply a type constructor name to type variable binders.+applyTyToTvbs :: Name -> [TyVarBndr_ flag] -> Type+applyTyToTvbs = List.foldl' (\a -> AppT a . tyVarBndrToType) . ConT++-- | Split a type signature by the arrows on its spine. For example, this:+--+-- @+-- forall a b. (a -> b) -> Char -> ()+-- @+--+-- would split to this:+--+-- @+-- ([a, b], [a -> b, Char, ()])+-- @+uncurryTy :: Type -> ([TyVarBndrSpec], [Type])+uncurryTy (AppT (AppT ArrowT t1) t2) =+  let (tvbs, tys) = uncurryTy t2+  in (tvbs, t1:tys)+uncurryTy (SigT t _) = uncurryTy t+uncurryTy (ForallT tvbs _ t) =+  let (tvbs', tys) = uncurryTy t+  in (tvbs ++ tvbs', tys)+uncurryTy t = ([], [t])++-- | Like uncurryType, except on a kind level.+uncurryKind :: Kind -> ([TyVarBndrSpec], [Kind])+uncurryKind = uncurryTy++tyVarBndrToType :: TyVarBndr_ flag -> Type+tyVarBndrToType = elimTV VarT (\n k -> SigT (VarT n) k)++-- | Generate a list of fresh names with a common prefix, and numbered suffixes.+newNameList :: String -> Int -> Q [Name]+newNameList prefix n = mapM (newName . (prefix ++) . show) [1..n]++-- | Checks to see if the last types in a data family instance can be safely eta-+-- reduced (i.e., dropped), given the other types. This checks for three conditions:+--+-- (1) All of the dropped types are type variables+-- (2) All of the dropped types are distinct+-- (3) None of the remaining types mention any of the dropped types+canEtaReduce :: [Type] -> [Type] -> Bool+canEtaReduce remaining dropped =+       all isTyVar dropped+       -- Make sure not to pass something of type [Type], since Type+       -- didn't have an Ord instance until template-haskell-2.10.0.0+    && allDistinct droppedNames+    && not (any (`mentionsName` droppedNames) remaining)+  where+    droppedNames :: [Name]+    droppedNames = map varTToName dropped++-- | Extract the Name from a type variable. If the argument Type is not a+-- type variable, throw an error.+varTToName :: Type -> Name+varTToName (VarT n)   = n+varTToName (SigT t _) = varTToName t+varTToName _          = error "Not a type variable!"++-- | Is the given type a variable?+isTyVar :: Type -> Bool+isTyVar VarT{}     = True+isTyVar (SigT t _) = isTyVar t+isTyVar _          = False++-- | Is the given kind a variable?+isKindVar :: Kind -> Bool+isKindVar = isTyVar++-- | Returns 'True' is a 'Type' contains no type variables.+isTypeMonomorphic :: Type -> Bool+isTypeMonomorphic = go+  where+    go :: Type -> Bool+    go (AppT t1 t2) = go t1 && go t2+    go (SigT t k)   = go t && go k+    go VarT{}       = False+    go _            = True++-- | Peel off a kind signature from a Type (if it has one).+unSigT :: Type -> Type+unSigT (SigT t _) = t+unSigT t          = t++-- | Peel off a kind signature from a TyVarBndr (if it has one).+unKindedTV :: TyVarBndrUnit -> TyVarBndrUnit+unKindedTV tvb = elimTV (\_ -> tvb) (\n _ -> plainTV n) tvb++-- | Does the given type mention any of the Names in the list?+mentionsName :: Type -> [Name] -> Bool+mentionsName = go+  where+    go :: Type -> [Name] -> Bool+    go (AppT t1 t2) names = go t1 names || go t2 names+    go (SigT t k)   names = go t names || go k names+    go (VarT n)     names = n `elem` names+    go _            _     = False++-- | Are all of the items in a list (which have an ordering) distinct?+--+-- This uses Set (as opposed to nub) for better asymptotic time complexity.+allDistinct :: Ord a => [a] -> Bool+allDistinct = allDistinct' Set.empty+  where+    allDistinct' :: Ord a => Set a -> [a] -> Bool+    allDistinct' uniqs (x:xs)+        | x `Set.member` uniqs = False+        | otherwise            = allDistinct' (Set.insert x uniqs) xs+    allDistinct' _ _           = True++fst3 :: (a, b, c) -> a+fst3 (a, _, _) = a++snd3 :: (a, b, c) -> b+snd3 (_, b, _) = b++trd3 :: (a, b, c) -> c+trd3 (_, _, c) = c++shrink :: (a, b, c) -> (b, c)+shrink (_, b, c) = (b, c)++foldBal :: (a -> a -> a) -> a -> [a] -> a+{-# INLINE foldBal #-} -- inlined to produce specialised code for each op+foldBal op0 x0 xs0 = fold_bal op0 x0 (length xs0) xs0+  where+    fold_bal op x !n xs = case xs of+      []  -> x+      [a] -> a+      _   -> let !nl = n `div` 2+                 !nr = n - nl+                 (l,r) = splitAt nl xs+             in fold_bal op x nl l+                `op` fold_bal op x nr r++isNewtypeVariant :: DatatypeVariant_ -> Bool+isNewtypeVariant Datatype_             = False+isNewtypeVariant Newtype_              = True+isNewtypeVariant (DataInstance_ {})    = False+isNewtypeVariant (NewtypeInstance_ {}) = True++-- | Indicates whether Generic or Generic1 is being derived.+data GenericClass = Generic | Generic1 deriving Enum++-- | Records information about the type variables of a data type with a+-- 'Generic' or 'Generic1' instance.+data GenericTvbs+    -- | Information about a data type with a 'Generic' instance.+  = Gen0+      { gen0Tvbs :: [TyVarBndrUnit]+        -- ^ All of the type variable arguments to the data type.+      }+    -- | Information about a data type with a 'Generic1' instance.+  | Gen1+      { gen1InitTvbs :: [TyVarBndrUnit]+        -- ^ All of the type variable arguments to the data type except the+        --   last one. In a @'Generic1' (T a_1 ... a_(n-1))@ instance, the+        --   'gen1InitTvbs' would be @[a_1, ..., a_(n-1)]@.+      , gen1LastTvbName :: Name+        -- ^ The name of the last type variable argument to the data type.+        --   In a @'Generic1' (T a_1 ... a_(n-1))@ instance, the+        --   'gen1LastTvbName' name would be @a_n@.+     , gen1LastTvbKindVar :: Maybe Name+        -- ^ If the 'gen1LastTvbName' has kind @k@, where @k@ is some kind+        --   variable, then the 'gen1LastTvbKindVar' is @'Just' k@. Otherwise,+        --   the 'gen1LastTvbKindVar' is 'Nothing'.+      }++-- | Compute 'GenericTvbs' from a 'GenericClass' and the type variable+-- arguments to a data type.+mkGenericTvbs :: GenericClass -> [Type] -> GenericTvbs+mkGenericTvbs gClass tySynVars =+  case gClass of+    Generic  -> Gen0{gen0Tvbs = freeVariablesWellScoped tySynVars}+    Generic1 -> Gen1{ gen1InitTvbs       = freeVariablesWellScoped initArgs+                    , gen1LastTvbName    = varTToName lastArg+                    , gen1LastTvbKindVar = mbLastArgKindName+                    }+  where+    -- Everything below is only used for Generic1.+    initArgs :: [Type]+    initArgs = init tySynVars++    lastArg :: Type+    lastArg = last tySynVars++    mbLastArgKindName :: Maybe Name+    mbLastArgKindName = starKindStatusToName+                      $ canRealizeKindStar lastArg++-- | Return the type variable arguments to a data type that appear in a+-- 'Generic' or 'Generic1' instance. For a 'Generic' instance, this consists of+-- all the type variable arguments. For a 'Generic1' instance, this consists of+-- all the type variable arguments except for the last one.+genericInitTvbs :: GenericTvbs -> [TyVarBndrUnit]+genericInitTvbs (Gen0{gen0Tvbs = tvbs})     = tvbs+genericInitTvbs (Gen1{gen1InitTvbs = tvbs}) = tvbs++-- | A version of 'DatatypeVariant' in which the data family instance+-- constructors come equipped with the 'ConstructorInfo' of the first+-- constructor in the family instance (for 'Name' generation purposes).+data DatatypeVariant_+  = Datatype_+  | Newtype_+  | DataInstance_    ConstructorInfo+  | NewtypeInstance_ ConstructorInfo++showsDatatypeVariant :: DatatypeVariant_ -> ShowS+showsDatatypeVariant variant = (++ '_':label)+  where+    dataPlain :: String+    dataPlain = "Plain"++    dataFamily :: ConstructorInfo -> String+    dataFamily con = "Family_" ++ sanitizeName (nameBase $ constructorName con)++    label :: String+    label = case variant of+              Datatype_            -> dataPlain+              Newtype_             -> dataPlain+              DataInstance_    con -> dataFamily con+              NewtypeInstance_ con -> dataFamily con++showNameQual :: Name -> String+showNameQual = sanitizeName . showQual+  where+    showQual (Name _ (NameQ m))       = modString m+    showQual (Name _ (NameG _ pkg m)) = pkgString pkg ++ ":" ++ modString m+    showQual _                        = ""++-- | Credit to Víctor López Juan for this trick+sanitizeName :: String -> String+sanitizeName nb = 'N':(+    nb >>= \x -> case x of+      c | isAlphaNum c || c == '\''-> [c]+      '_' -> "__"+      c   -> "_" ++ show (ord c))++-- | One of the last type variables cannot be eta-reduced (see the canEtaReduce+-- function for the criteria it would have to meet).+etaReductionError :: Type -> Q a+etaReductionError instanceType = fail $+  "Cannot eta-reduce to an instance of form \n\tinstance (...) => "+  ++ pprint instanceType++-- | Either the given data type doesn't have enough type variables, or one of+-- the type variables to be eta-reduced cannot realize kind *.+derivingKindError :: Name -> Q a+derivingKindError tyConName = fail+  . showString "Cannot derive well-kinded instance of form ‘Generic1 "+  . showParen True+    ( showString (nameBase tyConName)+    . showString " ..."+    )+  . showString "‘\n\tClass Generic1 expects an argument of kind "+#if MIN_VERSION_base(4,10,0)+  . showString "k -> *"+#else+  . showString "* -> *"+#endif+  $ ""++-- | The data type mentions the last type variable in a place other+-- than the last position of a data type in a constructor's field.+outOfPlaceTyVarError :: Q a+outOfPlaceTyVarError = fail+  . showString "Constructor must only use its last type variable as"+  . showString " the last argument of a data type"+  $ ""++-- | The data type mentions the last type variable in a type family+-- application.+typeFamilyApplicationError :: Q a+typeFamilyApplicationError = fail+  . showString "Constructor must not apply its last type variable"+  . showString " to an unsaturated type family"+  $ ""++-- | We cannot define implementations for @from(1)@ or @to(1)@ at the term level+-- for @type data@ declarations, which only exist at the type level.+typeDataError :: Name -> Q a+typeDataError dataName = fail+  . showString "Cannot derive instance for ‘"+  . showString (nameBase dataName)+  . showString "‘, which is a ‘type data‘ declaration"+  $ ""++-- | Cannot have a constructor argument of form (forall a1 ... an. <type>)+-- when deriving Generic(1)+rankNError :: Q a+rankNError = fail "Cannot have polymorphic arguments"++-- | Boilerplate for top level splices.+--+-- The given Name must meet one of two criteria:+--+-- 1. It must be the name of a type constructor of a plain data type or newtype.+-- 2. It must be the name of a data family instance or newtype instance constructor.+--+-- Any other value will result in an exception.+reifyDataInfo :: Name+              -> Q (Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_))+reifyDataInfo name = do+  return $ Left $ ns ++ " Could not reify " ++ nameBase name+ `recover`+  do DatatypeInfo { datatypeContext   = ctxt+                  , datatypeName      = parentName+                  , datatypeInstTypes = tys+                  , datatypeVariant   = variant+                  , datatypeCons      = cons+                  } <- reifyDatatype name+     variant_ <-+       case variant of+         Datatype          -> return Datatype_+         Newtype           -> return Newtype_+         DataInstance      -> return $ DataInstance_    $ headDataFamInstCon parentName cons+         NewtypeInstance   -> return $ NewtypeInstance_ $ headDataFamInstCon parentName cons+#if MIN_VERSION_th_abstraction(0,5,0)+         Datatype.TypeData -> typeDataError parentName+#endif+     checkDataContext parentName ctxt $ Right (parentName, tys, cons, variant_)+  where+    ns :: String+    ns = "Generics.Deriving.TH.reifyDataInfo: "++    -- This isn't total, but the API requires that the data family instance have+    -- at least one constructor anyways, so this will always succeed.+    headDataFamInstCon :: Name -> [ConstructorInfo] -> ConstructorInfo+    headDataFamInstCon dataFamName cons =+      case cons of+        con:_ -> con+        [] -> error $ "reified data family instance without a data constructor: "+                   ++ nameBase dataFamName++-- | One cannot derive Generic(1) instance for anything that uses DatatypeContexts,+-- so check to make sure the Cxt field of a datatype is null.+checkDataContext :: Name -> Cxt -> a -> Q a+checkDataContext _        [] x = return x+checkDataContext dataName _  _ = fail $+  nameBase dataName ++ " must not have a datatype context"++-- | Deriving Generic(1) doesn't work with ExistentialQuantification or GADTs.+checkExistentialContext :: Name -> [TyVarBndrUnit] -> Cxt -> Q ()+checkExistentialContext constrName vars ctxt =+  unless (null vars && null ctxt) $ fail $+    nameBase constrName ++ " must be a vanilla data constructor"++#if !(MIN_VERSION_template_haskell(2,21,0)) && !(MIN_VERSION_th_abstraction(0,6,0))+type TyVarBndrVis = TyVarBndrUnit++bndrReq :: ()+bndrReq = ()+#endif++-------------------------------------------------------------------------------+-- Quoted names+-------------------------------------------------------------------------------++comp1DataName :: Name+comp1DataName = 'Comp1++infixDataName :: Name+infixDataName = 'GD.Infix++k1DataName :: Name+k1DataName = 'K1++l1DataName :: Name+l1DataName = 'L1++leftAssociativeDataName :: Name+leftAssociativeDataName = 'LeftAssociative++m1DataName :: Name+m1DataName = 'M1++notAssociativeDataName :: Name+notAssociativeDataName = 'NotAssociative++par1DataName :: Name+par1DataName = 'Par1++prefixDataName :: Name+prefixDataName = 'Prefix++productDataName :: Name+productDataName = '(:*:)++r1DataName :: Name+r1DataName = 'R1++rec1DataName :: Name+rec1DataName = 'Rec1++rightAssociativeDataName :: Name+rightAssociativeDataName = 'RightAssociative++u1DataName :: Name+u1DataName = 'U1++uAddrDataName :: Name+uAddrDataName = 'UAddr++uCharDataName :: Name+uCharDataName = 'UChar++uDoubleDataName :: Name+uDoubleDataName = 'UDouble++uFloatDataName :: Name+uFloatDataName = 'UFloat++uIntDataName :: Name+uIntDataName = 'UInt++uWordDataName :: Name+uWordDataName = 'UWord++c1TypeName :: Name+c1TypeName = ''C1++composeTypeName :: Name+composeTypeName = ''(:.:)++constructorTypeName :: Name+constructorTypeName = ''Constructor++d1TypeName :: Name+d1TypeName = ''D1++genericTypeName :: Name+genericTypeName = ''Generic++generic1TypeName :: Name+generic1TypeName = ''Generic1++datatypeTypeName :: Name+datatypeTypeName = ''Datatype++par1TypeName :: Name+par1TypeName = ''Par1++productTypeName :: Name+productTypeName = ''(:*:)++rec0TypeName :: Name+rec0TypeName = ''Rec0++rec1TypeName :: Name+rec1TypeName = ''Rec1++repTypeName :: Name+repTypeName = ''Rep++rep1TypeName :: Name+rep1TypeName = ''Rep1++s1TypeName :: Name+s1TypeName = ''S1++selectorTypeName :: Name+selectorTypeName = ''Selector++sumTypeName :: Name+sumTypeName = ''(:+:)++u1TypeName :: Name+u1TypeName = ''U1++uAddrTypeName :: Name+uAddrTypeName = ''UAddr++uCharTypeName :: Name+uCharTypeName = ''UChar++uDoubleTypeName :: Name+uDoubleTypeName = ''UDouble++uFloatTypeName :: Name+uFloatTypeName = ''UFloat++uIntTypeName :: Name+uIntTypeName = ''UInt++uWordTypeName :: Name+uWordTypeName = ''UWord++v1TypeName :: Name+v1TypeName = ''V1++conFixityValName :: Name+conFixityValName = 'conFixity++conIsRecordValName :: Name+conIsRecordValName = 'conIsRecord++conNameValName :: Name+conNameValName = 'GD.conName++datatypeNameValName :: Name+datatypeNameValName = 'GD.datatypeName++isNewtypeValName :: Name+isNewtypeValName = 'isNewtype++fromValName :: Name+fromValName = 'from++from1ValName :: Name+from1ValName = 'from1++moduleNameValName :: Name+moduleNameValName = 'moduleName++selNameValName :: Name+selNameValName = 'selName++seqValName :: Name+seqValName = 'seq++toValName :: Name+toValName = 'to++to1ValName :: Name+to1ValName = 'to1++uAddrHashValName :: Name+uAddrHashValName = 'uAddr#++uCharHashValName :: Name+uCharHashValName = 'uChar#++uDoubleHashValName :: Name+uDoubleHashValName = 'uDouble#++uFloatHashValName :: Name+uFloatHashValName = 'uFloat#++uIntHashValName :: Name+uIntHashValName = 'uInt#++uWordHashValName :: Name+uWordHashValName = 'uWord#++unComp1ValName :: Name+unComp1ValName = 'unComp1++unK1ValName :: Name+unK1ValName = 'unK1++unPar1ValName :: Name+unPar1ValName = 'unPar1++unRec1ValName :: Name+unRec1ValName = 'unRec1++trueDataName, falseDataName :: Name+trueDataName  = 'True+falseDataName = 'False++nothingDataName, justDataName :: Name+nothingDataName = 'Nothing+justDataName    = 'Just++addrHashTypeName :: Name+addrHashTypeName = ''Addr#++charHashTypeName :: Name+charHashTypeName = ''Char#++doubleHashTypeName :: Name+doubleHashTypeName = ''Double#++floatHashTypeName :: Name+floatHashTypeName = ''Float#++intHashTypeName :: Name+intHashTypeName = ''Int#++wordHashTypeName :: Name+wordHashTypeName = ''Word#++composeValName :: Name+composeValName = '(.)++errorValName :: Name+errorValName = 'error++fmapValName :: Name+fmapValName = 'fmap++undefinedValName :: Name+undefinedValName = 'undefined++decidedLazyDataName :: Name+decidedLazyDataName = 'GD.DecidedLazy++decidedStrictDataName :: Name+decidedStrictDataName = 'GD.DecidedStrict++decidedUnpackDataName :: Name+decidedUnpackDataName = 'GD.DecidedUnpack++infixIDataName :: Name+infixIDataName = 'InfixI++metaConsDataName :: Name+metaConsDataName = 'MetaCons++metaDataDataName :: Name+metaDataDataName = 'MetaData++metaSelDataName :: Name+metaSelDataName = 'MetaSel++noSourceStrictnessDataName :: Name+noSourceStrictnessDataName = 'GD.NoSourceStrictness++noSourceUnpackednessDataName :: Name+noSourceUnpackednessDataName = 'GD.NoSourceUnpackedness++prefixIDataName :: Name+prefixIDataName = 'PrefixI++sourceLazyDataName :: Name+sourceLazyDataName = 'GD.SourceLazy++sourceNoUnpackDataName :: Name+sourceNoUnpackDataName = 'GD.SourceNoUnpack++sourceStrictDataName :: Name+sourceStrictDataName = 'GD.SourceStrict++sourceUnpackDataName :: Name+sourceUnpackDataName = 'GD.SourceUnpack++packageNameValName :: Name+packageNameValName = 'packageName
+ src/Generics/Deriving/TH/Post4_9.hs view
@@ -0,0 +1,137 @@+{- |+Module      :  Generics.Deriving.TH.Post4_9+Copyright   :  (c) 2008--2009 Universiteit Utrecht+License     :  BSD3++Maintainer  :  generics@haskell.org+Stability   :  experimental+Portability :  non-portable++Template Haskell machinery for the type-literal-based variant of GHC+generics introduced in @base-4.9@.+-}++module Generics.Deriving.TH.Post4_9 (+      deriveMeta+    , deriveData+    , deriveConstructors+    , deriveSelectors+    , mkMetaDataType+    , mkMetaConsType+    , mkMetaSelType+    , SelStrictInfo(..)+    , reifySelStrictInfo+  ) where++import Data.Maybe (fromMaybe)++import Generics.Deriving.TH.Internal++import Language.Haskell.TH.Datatype as THAbs+import Language.Haskell.TH.Lib+import Language.Haskell.TH.Syntax++mkMetaDataType :: DatatypeVariant_ -> Name -> Q Type+mkMetaDataType dv n =+           promotedT metaDataDataName+    `appT` litT (strTyLit (nameBase n))+    `appT` litT (strTyLit m)+    `appT` litT (strTyLit pkg)+    `appT` promoteBool (isNewtypeVariant dv)+  where+    m, pkg :: String+    m   = fromMaybe (error "Cannot fetch module name!")  (nameModule n)+    pkg = fromMaybe (error "Cannot fetch package name!") (namePackage n)++mkMetaConsType :: DatatypeVariant_ -> Name -> Name -> Bool -> Bool -> Q Type+mkMetaConsType _ _ n conIsRecord conIsInfix = do+    mbFi <- reifyFixity n+    promotedT metaConsDataName+      `appT` litT (strTyLit (nameBase n))+      `appT` fixityIPromotedType mbFi conIsInfix+      `appT` promoteBool conIsRecord++promoteBool :: Bool -> Q Type+promoteBool True  = promotedT trueDataName+promoteBool False = promotedT falseDataName++fixityIPromotedType :: Maybe Fixity -> Bool -> Q Type+fixityIPromotedType mbFi True =+           promotedT infixIDataName+    `appT` promoteAssociativity a+    `appT` litT (numTyLit (toInteger n))+  where+    Fixity n a = fromMaybe defaultFixity mbFi+fixityIPromotedType _ False = promotedT prefixIDataName++promoteAssociativity :: FixityDirection -> Q Type+promoteAssociativity InfixL = promotedT leftAssociativeDataName+promoteAssociativity InfixR = promotedT rightAssociativeDataName+promoteAssociativity InfixN = promotedT notAssociativeDataName++mkMetaSelType :: DatatypeVariant_ -> Name -> Name -> Maybe Name+              -> SelStrictInfo -> Q Type+mkMetaSelType _ _ _ mbF (SelStrictInfo su ss ds) =+    let mbSelNameT = case mbF of+            Just f  -> promotedT justDataName `appT` litT (strTyLit (nameBase f))+            Nothing -> promotedT nothingDataName+    in promotedT metaSelDataName+        `appT` mbSelNameT+        `appT` promoteUnpackedness su+        `appT` promoteStrictness ss+        `appT` promoteDecidedStrictness ds++data SelStrictInfo = SelStrictInfo Unpackedness Strictness DecidedStrictness++promoteUnpackedness :: Unpackedness -> Q Type+promoteUnpackedness UnspecifiedUnpackedness = promotedT noSourceUnpackednessDataName+promoteUnpackedness NoUnpack                = promotedT sourceNoUnpackDataName+promoteUnpackedness Unpack                  = promotedT sourceUnpackDataName++promoteStrictness :: Strictness -> Q Type+promoteStrictness UnspecifiedStrictness = promotedT noSourceStrictnessDataName+promoteStrictness Lazy                  = promotedT sourceLazyDataName+promoteStrictness THAbs.Strict          = promotedT sourceStrictDataName++promoteDecidedStrictness :: DecidedStrictness -> Q Type+promoteDecidedStrictness DecidedLazy   = promotedT decidedLazyDataName+promoteDecidedStrictness DecidedStrict = promotedT decidedStrictDataName+promoteDecidedStrictness DecidedUnpack = promotedT decidedUnpackDataName++reifySelStrictInfo :: Name -> [FieldStrictness] -> Q [SelStrictInfo]+reifySelStrictInfo conName fs = do+    dcdStrs <- reifyConStrictness conName+    let srcUnpks = map fieldUnpackedness fs+        srcStrs  = map fieldStrictness   fs+    return $ zipWith3 SelStrictInfo srcUnpks srcStrs dcdStrs++-- | Given the type and the name (as string) for the type to derive,+-- generate the 'Data' instance, the 'Constructor' instances, and the 'Selector'+-- instances.+--+-- On GHC 7.11 and up, this functionality is no longer used in GHC generics,+-- so this function generates no declarations.+deriveMeta :: Name -> Q [Dec]+deriveMeta _ = return []++-- | Given a datatype name, derive a datatype and instance of class 'Datatype'.+--+-- On GHC 7.11 and up, this functionality is no longer used in GHC generics,+-- so this function generates no declarations.+deriveData :: Name -> Q [Dec]+deriveData _ = return []++-- | Given a datatype name, derive datatypes and+-- instances of class 'Constructor'.+--+-- On GHC 7.11 and up, this functionality is no longer used in GHC generics,+-- so this function generates no declarations.+deriveConstructors :: Name -> Q [Dec]+deriveConstructors _ = return []++-- | Given a datatype name, derive datatypes and instances of class 'Selector'.+--+-- On GHC 7.11 and up, this functionality is no longer used in GHC generics,+-- so this function generates no declarations.+deriveSelectors :: Name -> Q [Dec]+deriveSelectors _ = return []
src/Generics/Deriving/Traversable.hs view
@@ -1,82 +1,184 @@-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
-module Generics.Deriving.Traversable (
-  -- * GTraversable class
-    GTraversable(..)
-
-  -- * Default method
-  , gtraversedefault
-
-  ) where
-
-import Control.Applicative
-import Generics.Deriving.Base
-import Generics.Deriving.Foldable
-import Generics.Deriving.Functor
-import Generics.Deriving.Instances ()
-
---------------------------------------------------------------------------------
--- Generic traverse
---------------------------------------------------------------------------------
-
-class GTraversable' t where
-  gtraverse' :: Applicative f => (a -> f b) -> t a -> f (t b)
-
-instance GTraversable' U1 where
-  gtraverse' _ U1 = pure U1
-
-instance GTraversable' Par1 where
-  gtraverse' f (Par1 a) = Par1 <$> f a
-
-instance GTraversable' (K1 i c) where
-  gtraverse' _ (K1 a) = pure (K1 a)
-
-instance (GTraversable f) => GTraversable' (Rec1 f) where
-  gtraverse' f (Rec1 a) = Rec1 <$> gtraverse f a
-
-instance (GTraversable' f) => GTraversable' (M1 i c f) where
-  gtraverse' f (M1 a) = M1 <$> gtraverse' f a
-
-instance (GTraversable' f, GTraversable' g) => GTraversable' (f :+: g) where
-  gtraverse' f (L1 a) = L1 <$> gtraverse' f a
-  gtraverse' f (R1 a) = R1 <$> gtraverse' f a
-
-instance (GTraversable' f, GTraversable' g) => GTraversable' (f :*: g) where
-  gtraverse' f (a :*: b) = (:*:) <$> gtraverse' f a <*> gtraverse' f b
-
-instance (GTraversable f, GTraversable' g) => GTraversable' (f :.: g) where
-  gtraverse' f (Comp1 x) = Comp1 <$> gtraverse (gtraverse' f) x
-
-
-class (GFunctor t, GFoldable t) => GTraversable t where
-  gtraverse :: Applicative f => (a -> f b) -> t a -> f (t b)
-#if __GLASGOW_HASKELL__ >= 701
-  default gtraverse :: (Generic1 t, GTraversable' (Rep1 t), Applicative f)
-                    => (a -> f b) -> t a -> f (t b)
-  gtraverse = gtraversedefault
-#endif
-
-  gsequenceA :: Applicative f => t (f a) -> f (t a)
-  gsequenceA = gtraverse id
-
-  gmapM :: Monad m => (a -> m b) -> t a -> m (t b)
-  gmapM f = unwrapMonad . gtraverse (WrapMonad . f)
-
-  gsequence :: Monad m => t (m a) -> m (t a)
-  gsequence = gmapM id
-
-gtraversedefault :: (Generic1 t, GTraversable' (Rep1 t), Applicative f)
-                 => (a -> f b) -> t a -> f (t b)
-gtraversedefault f x = to1 <$> gtraverse' f (from1 x)
-
--- Base types instances
-instance GTraversable Maybe where
-  gtraverse = gtraversedefault
-
-instance GTraversable [] where
-  gtraverse = gtraversedefault
+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Safe #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Generics.Deriving.Traversable (+  -- * Generic Traversable class+    GTraversable(..)++  -- * Default method+  , gtraversedefault++  -- * Internal Traversable class+  , GTraversable'(..)++  ) where++import           Control.Applicative (Const, WrappedMonad(..), ZipList)++import           Data.Complex (Complex)+import           Data.Functor.Identity (Identity)+import qualified Data.Functor.Product as Functor (Product)+import qualified Data.Functor.Sum as Functor (Sum)+import           Data.List.NonEmpty (NonEmpty)+import qualified Data.Monoid as Monoid (First, Last, Product, Sum)+import           Data.Monoid (Dual)+import           Data.Ord (Down)+import           Data.Proxy (Proxy)+import qualified Data.Semigroup as Semigroup (First, Last)+import           Data.Semigroup (Arg, Max, Min, WrappedMonoid)++import           Generics.Deriving.Base+import           Generics.Deriving.Foldable+import           Generics.Deriving.Functor++--------------------------------------------------------------------------------+-- Generic traverse+--------------------------------------------------------------------------------++class GTraversable' t where+  gtraverse' :: Applicative f => (a -> f b) -> t a -> f (t b)++instance GTraversable' V1 where+  gtraverse' _ x = pure $ case x of {}++instance GTraversable' U1 where+  gtraverse' _ U1 = pure U1++instance GTraversable' Par1 where+  gtraverse' f (Par1 a) = Par1 <$> f a++instance GTraversable' (K1 i c) where+  gtraverse' _ (K1 a) = pure (K1 a)++instance (GTraversable f) => GTraversable' (Rec1 f) where+  gtraverse' f (Rec1 a) = Rec1 <$> gtraverse f a++instance (GTraversable' f) => GTraversable' (M1 i c f) where+  gtraverse' f (M1 a) = M1 <$> gtraverse' f a++instance (GTraversable' f, GTraversable' g) => GTraversable' (f :+: g) where+  gtraverse' f (L1 a) = L1 <$> gtraverse' f a+  gtraverse' f (R1 a) = R1 <$> gtraverse' f a++instance (GTraversable' f, GTraversable' g) => GTraversable' (f :*: g) where+  gtraverse' f (a :*: b) = (:*:) <$> gtraverse' f a <*> gtraverse' f b++instance (GTraversable f, GTraversable' g) => GTraversable' (f :.: g) where+  gtraverse' f (Comp1 x) = Comp1 <$> gtraverse (gtraverse' f) x++instance GTraversable' UAddr where+  gtraverse' _ (UAddr a) = pure (UAddr a)++instance GTraversable' UChar where+  gtraverse' _ (UChar c) = pure (UChar c)++instance GTraversable' UDouble where+  gtraverse' _ (UDouble d) = pure (UDouble d)++instance GTraversable' UFloat where+  gtraverse' _ (UFloat f) = pure (UFloat f)++instance GTraversable' UInt where+  gtraverse' _ (UInt i) = pure (UInt i)++instance GTraversable' UWord where+  gtraverse' _ (UWord w) = pure (UWord w)++class (GFunctor t, GFoldable t) => GTraversable t where+  gtraverse :: Applicative f => (a -> f b) -> t a -> f (t b)+  default gtraverse :: (Generic1 t, GTraversable' (Rep1 t), Applicative f)+                    => (a -> f b) -> t a -> f (t b)+  gtraverse = gtraversedefault++  gsequenceA :: Applicative f => t (f a) -> f (t a)+  gsequenceA = gtraverse id++  gmapM :: Monad m => (a -> m b) -> t a -> m (t b)+  gmapM f = unwrapMonad . gtraverse (WrapMonad . f)++  gsequence :: Monad m => t (m a) -> m (t a)+  gsequence = gmapM id++gtraversedefault :: (Generic1 t, GTraversable' (Rep1 t), Applicative f)+                 => (a -> f b) -> t a -> f (t b)+gtraversedefault f x = to1 <$> gtraverse' f (from1 x)++-- Base types instances+instance GTraversable ((,) a) where+  gtraverse = gtraversedefault++instance GTraversable [] where+  gtraverse = gtraversedefault++instance GTraversable (Arg a) where+  gtraverse = gtraversedefault++instance GTraversable Complex where+  gtraverse = gtraversedefault++instance GTraversable (Const m) where+  gtraverse = gtraversedefault++instance GTraversable Down where+  gtraverse = gtraversedefault++instance GTraversable Dual where+  gtraverse = gtraversedefault++instance GTraversable (Either a) where+  gtraverse = gtraversedefault++instance GTraversable Monoid.First where+  gtraverse = gtraversedefault++instance GTraversable (Semigroup.First) where+  gtraverse = gtraversedefault++instance GTraversable Identity where+  gtraverse = gtraversedefault++instance GTraversable Monoid.Last where+  gtraverse = gtraversedefault++instance GTraversable Semigroup.Last where+  gtraverse = gtraversedefault++instance GTraversable Max where+  gtraverse = gtraversedefault++instance GTraversable Maybe where+  gtraverse = gtraversedefault++instance GTraversable Min where+  gtraverse = gtraversedefault++instance GTraversable NonEmpty where+  gtraverse = gtraversedefault++instance GTraversable Monoid.Product where+  gtraverse = gtraversedefault++instance (GTraversable f, GTraversable g) => GTraversable (Functor.Product f g) where+  gtraverse = gtraversedefault++instance GTraversable Proxy where+  gtraverse = gtraversedefault++instance GTraversable Monoid.Sum where+  gtraverse = gtraversedefault++instance (GTraversable f, GTraversable g) => GTraversable (Functor.Sum f g) where+  gtraverse = gtraversedefault++instance GTraversable WrappedMonoid where+  gtraverse = gtraversedefault++instance GTraversable ZipList where+  gtraverse = gtraversedefault
src/Generics/Deriving/Uniplate.hs view
@@ -1,355 +1,345 @@-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# LANGUAGE OverlappingInstances #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE DefaultSignatures #-}
-#endif
-
---------------------------------------------------------------------------------
--- |
--- Module      :  Generics.Deriving.Uniplate
--- Copyright   :  2011-2012 Universiteit Utrecht, University of Oxford
--- License     :  BSD3
---
--- Maintainer  :  generics@haskell.org
--- Stability   :  experimental
--- Portability :  non-portable
---
--- Summary: Functions inspired by the Uniplate generic programming library,
--- mostly implemented by Sean Leather.
---------------------------------------------------------------------------------
-
-module Generics.Deriving.Uniplate (
-    Uniplate(..)
-
-  -- * Derived functions
-  , uniplate
-  , universe
-  , rewrite
-  , rewriteM
-  , contexts
-  , holes
-  , para
-
-  -- * Default definitions
-  , childrendefault
-  , contextdefault
-  , descenddefault
-  , descendMdefault
-  , transformdefault
-  , transformMdefault
-
-  ) where
-
-
-import Generics.Deriving.Base
-import Generics.Deriving.Instances ()
-
-import Control.Monad (liftM, liftM2)
-import GHC.Exts (build)
-
---------------------------------------------------------------------------------
--- Generic Uniplate
---------------------------------------------------------------------------------
-
-class Uniplate' f b where
-  children'  :: f a -> [b]
-  descend'   :: (b -> b) -> f a -> f a
-  descendM'  :: Monad m => (b -> m b) -> f a -> m (f a)
-  transform' :: (b -> b) -> f a -> f a
-  transformM'  :: Monad m => (b -> m b) -> f a -> m (f a)
-
-instance Uniplate' U1 a where
-  children' U1 = []
-  descend' _ U1 = U1
-  descendM' _ U1 = return U1
-  transform' _ U1 = U1
-  transformM' _ U1 = return U1
-
-instance (Uniplate a) => Uniplate' (K1 i a) a where
-  children' (K1 a) = [a]
-  descend' f (K1 a) = K1 (f a)
-  descendM' f (K1 a) = liftM K1 (f a)
-  transform' f (K1 a) = K1 (transform f a)
-  transformM' f (K1 a) = liftM K1 (transformM f a)
-
-instance Uniplate' (K1 i a) b where
-  children' (K1 _) = []
-  descend' _ (K1 a) = K1 a
-  descendM' _ (K1 a) = return (K1 a)
-  transform' _ (K1 a) = K1 a
-  transformM' _ (K1 a) = return (K1 a)
-
-instance (Uniplate' f b) => Uniplate' (M1 i c f) b where
-  children' (M1 a) = children' a
-  descend' f (M1 a) = M1 (descend' f a)
-  descendM' f (M1 a) = liftM M1 (descendM' f a)
-  transform' f (M1 a) = M1 (transform' f a)
-  transformM' f (M1 a) = liftM M1 (transformM' f a)
-
-instance (Uniplate' f b, Uniplate' g b) => Uniplate' (f :+: g) b where
-  children' (L1 a) = children' a
-  children' (R1 a) = children' a
-  descend' f (L1 a) = L1 (descend' f a)
-  descend' f (R1 a) = R1 (descend' f a)
-  descendM' f (L1 a) = liftM L1 (descendM' f a)
-  descendM' f (R1 a) = liftM R1 (descendM' f a)
-  transform' f (L1 a) = L1 (transform' f a)
-  transform' f (R1 a) = R1 (transform' f a)
-  transformM' f (L1 a) = liftM L1 (transformM' f a)
-  transformM' f (R1 a) = liftM R1 (transformM' f a)
-
-instance (Uniplate' f b, Uniplate' g b) => Uniplate' (f :*: g) b where
-  children' (a :*: b) = children' a ++ children' b 
-  descend' f (a :*: b) = descend' f a :*: descend' f b 
-  descendM' f (a :*: b) = liftM2 (:*:) (descendM' f a) (descendM' f b)
-  transform' f (a :*: b) = transform' f a :*: transform' f b
-  transformM' f (a :*: b) = liftM2 (:*:) (transformM' f a) (transformM' f b)
-
-
--- Context' is a separate class from Uniplate' since it uses special product
--- instances, but the context function still appears in Uniplate.
-class Context' f b where
-  context' :: f a -> [b] -> f a
-
-instance Context' U1 b where
-  context' U1 _ = U1
-
-instance Context' (K1 i a) a where
-  context' _      []    = error "Generics.Deriving.Uniplate.context: empty list"
-  context' (K1 _) (c:_) = K1 c
-
-instance Context' (K1 i a) b where
-  context' (K1 a) _ = K1 a
-
-instance (Context' f b) => Context' (M1 i c f) b where
-  context' (M1 a) cs = M1 (context' a cs)
-
-instance (Context' f b, Context' g b) => Context' (f :+: g) b where
-  context' (L1 a) cs = L1 (context' a cs)
-  context' (R1 a) cs = R1 (context' a cs)
-
-instance (Context' g a) => Context' (M1 i c (K1 j a) :*: g) a where
-  context' _                 []     = error "Generics.Deriving.Uniplate.context: empty list"
-  context' (M1 (K1 _) :*: b) (c:cs) = M1 (K1 c) :*: context' b cs
-
-instance (Context' g b) => Context' (f :*: g) b where
-  context' (a :*: b) cs = a :*: context' b cs
-
-
-class Uniplate a where 
-  children :: a -> [a]
-#if __GLASGOW_HASKELL__ >= 701
-  default children :: (Generic a, Uniplate' (Rep a) a) => a -> [a]
-  children = childrendefault
-#endif
-
-  context :: a -> [a] -> a
-#if __GLASGOW_HASKELL__ >= 701
-  default context :: (Generic a, Context' (Rep a) a) => a -> [a] -> a
-  context = contextdefault
-#endif
-
-  descend :: (a -> a) -> a -> a
-#if __GLASGOW_HASKELL__ >= 701
-  default descend :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a
-  descend = descenddefault
-#endif
-
-  descendM :: Monad m => (a -> m a) -> a -> m a
-#if __GLASGOW_HASKELL__ >= 701
-  default descendM :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a
-  descendM = descendMdefault
-#endif
-
-  transform :: (a -> a) -> a -> a
-#if __GLASGOW_HASKELL__ >= 701
-  default transform :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a
-  transform = transformdefault
-#endif
-
-  transformM :: Monad m => (a -> m a) -> a -> m a
-#if __GLASGOW_HASKELL__ >= 701
-  default transformM :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a
-  transformM = transformMdefault
-#endif
-
-childrendefault :: (Generic a, Uniplate' (Rep a) a) => a -> [a]
-childrendefault = children' . from
-
-contextdefault :: (Generic a, Context' (Rep a) a) => a -> [a] -> a
-contextdefault x cs = to (context' (from x) cs)
-
-descenddefault :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a
-descenddefault f = to . descend' f . from
-
-descendMdefault :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a
-descendMdefault f = liftM to . descendM' f . from
-
-transformdefault :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a
-transformdefault f = f . to . transform' f . from
-
-transformMdefault :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a
-transformMdefault f = liftM to . transformM' f . from
-
-
--- Derived functions (mostly copied from Neil Michell's code)
-
-uniplate :: Uniplate a => a -> ([a], [a] -> a)
-uniplate a = (children a, context a)
-
-universe :: Uniplate a => a -> [a]
-universe a = build (go a)
-  where
-    go x cons nil = cons x $ foldr ($) nil $ map (\c -> go c cons) $ children x
-
-rewrite :: Uniplate a => (a -> Maybe a) -> a -> a
-rewrite f = transform g
-  where
-    g x = maybe x (rewrite f) (f x)
-
-rewriteM :: (Monad m, Uniplate a) => (a -> m (Maybe a)) -> a -> m a
-rewriteM f = transformM g
-  where
-    g x = f x >>= maybe (return x) (rewriteM f)
-
-contexts :: Uniplate a => a -> [(a, a -> a)]
-contexts a = (a, id) : f (holes a)
-  where
-    f xs = [ (ch2, ctx1 . ctx2)
-           | (ch1, ctx1) <- xs
-           , (ch2, ctx2) <- contexts ch1]
-
-holes :: Uniplate a => a -> [(a, a -> a)]
-holes a = uncurry f (uniplate a)
-  where
-    f []     _   = []
-    f (x:xs) gen = (x, gen . (:xs)) : f xs (gen . (x:))
-
-para :: Uniplate a => (a -> [r] -> r) -> a -> r
-para f x = f x $ map (para f) $ children x
-
-
--- Base types instances
-instance Uniplate Bool where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate Char where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate Double where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate Float where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate Int where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate () where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-
--- Tuple instances
-instance Uniplate (b,c) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate (b,c,d) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate (b,c,d,e) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate (b,c,d,e,f) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate (b,c,d,e,f,g) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate (b,c,d,e,f,g,h) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-
--- Parameterized type instances
-instance Uniplate (Maybe a) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-instance Uniplate (Either a b) where
-  children _ = []
-  context x _ = x
-  descend _ = id
-  descendM _ = return
-  transform = id
-  transformM _ = return
-
-instance Uniplate [a] where
-  children []    = []
-  children (_:t) = [t]
-  context _     []    = error "Generics.Deriving.Uniplate.context: empty list"
-  context []    _     = []
-  context (h:_) (t:_) = h:t
-  descend _ []    = []
-  descend f (h:t) = h:f t
-  descendM _ []    = return []
-  descendM f (h:t) = f t >>= \t' -> return (h:t')
-  transform f []    = f []
-  transform f (h:t) = f (h:transform f t)
-  transformM f []    = f []
-  transformM f (h:t) = transformM f t >>= \t' -> f (h:t')
-
+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++{- |+Module      :  Generics.Deriving.Uniplate+Copyright   :  2011-2012 Universiteit Utrecht, University of Oxford+License     :  BSD3++Maintainer  :  generics@haskell.org+Stability   :  experimental+Portability :  non-portable++Summary: Functions inspired by the Uniplate generic programming library,+mostly implemented by Sean Leather.+-}++module Generics.Deriving.Uniplate (+  -- * Generic Uniplate class+    Uniplate(..)++  -- * Derived functions+  , uniplate+  , universe+  , rewrite+  , rewriteM+  , contexts+  , holes+  , para++  -- * Default definitions+  , childrendefault+  , contextdefault+  , descenddefault+  , descendMdefault+  , transformdefault+  , transformMdefault++  -- * Internal Uniplate class+  , Uniplate'(..)++  -- * Internal Context class+  , Context'(..)+  ) where+++import Generics.Deriving.Base++import Control.Monad (liftM, liftM2)+import GHC.Exts (build)++--------------------------------------------------------------------------------+-- Generic Uniplate+--------------------------------------------------------------------------------++class Uniplate' f b where+  children'  :: f a -> [b]+  descend'   :: (b -> b) -> f a -> f a+  descendM'  :: Monad m => (b -> m b) -> f a -> m (f a)+  transform' :: (b -> b) -> f a -> f a+  transformM'  :: Monad m => (b -> m b) -> f a -> m (f a)++instance Uniplate' U1 a where+  children' U1 = []+  descend' _ U1 = U1+  descendM' _ U1 = return U1+  transform' _ U1 = U1+  transformM' _ U1 = return U1++instance {-# OVERLAPPING #-} (Uniplate a) => Uniplate' (K1 i a) a where+  children' (K1 a) = [a]+  descend' f (K1 a) = K1 (f a)+  descendM' f (K1 a) = liftM K1 (f a)+  transform' f (K1 a) = K1 (transform f a)+  transformM' f (K1 a) = liftM K1 (transformM f a)++instance {-# OVERLAPPABLE #-} Uniplate' (K1 i a) b where+  children' (K1 _) = []+  descend' _ (K1 a) = K1 a+  descendM' _ (K1 a) = return (K1 a)+  transform' _ (K1 a) = K1 a+  transformM' _ (K1 a) = return (K1 a)++instance (Uniplate' f b) => Uniplate' (M1 i c f) b where+  children' (M1 a) = children' a+  descend' f (M1 a) = M1 (descend' f a)+  descendM' f (M1 a) = liftM M1 (descendM' f a)+  transform' f (M1 a) = M1 (transform' f a)+  transformM' f (M1 a) = liftM M1 (transformM' f a)++instance (Uniplate' f b, Uniplate' g b) => Uniplate' (f :+: g) b where+  children' (L1 a) = children' a+  children' (R1 a) = children' a+  descend' f (L1 a) = L1 (descend' f a)+  descend' f (R1 a) = R1 (descend' f a)+  descendM' f (L1 a) = liftM L1 (descendM' f a)+  descendM' f (R1 a) = liftM R1 (descendM' f a)+  transform' f (L1 a) = L1 (transform' f a)+  transform' f (R1 a) = R1 (transform' f a)+  transformM' f (L1 a) = liftM L1 (transformM' f a)+  transformM' f (R1 a) = liftM R1 (transformM' f a)++instance (Uniplate' f b, Uniplate' g b) => Uniplate' (f :*: g) b where+  children' (a :*: b) = children' a ++ children' b+  descend' f (a :*: b) = descend' f a :*: descend' f b+  descendM' f (a :*: b) = liftM2 (:*:) (descendM' f a) (descendM' f b)+  transform' f (a :*: b) = transform' f a :*: transform' f b+  transformM' f (a :*: b) = liftM2 (:*:) (transformM' f a) (transformM' f b)+++-- Context' is a separate class from Uniplate' since it uses special product+-- instances, but the context function still appears in Uniplate.+class Context' f b where+  context' :: f a -> [b] -> f a++instance Context' U1 b where+  context' U1 _ = U1++instance {-# OVERLAPPING #-} Context' (K1 i a) a where+  context' _      []    = error "Generics.Deriving.Uniplate.context: empty list"+  context' (K1 _) (c:_) = K1 c++instance {-# OVERLAPPABLE #-} Context' (K1 i a) b where+  context' (K1 a) _ = K1 a++instance (Context' f b) => Context' (M1 i c f) b where+  context' (M1 a) cs = M1 (context' a cs)++instance (Context' f b, Context' g b) => Context' (f :+: g) b where+  context' (L1 a) cs = L1 (context' a cs)+  context' (R1 a) cs = R1 (context' a cs)++instance {-# OVERLAPPING #-} (Context' g a) => Context' (M1 i c (K1 j a) :*: g) a where+  context' _                 []     = error "Generics.Deriving.Uniplate.context: empty list"+  context' (M1 (K1 _) :*: b) (c:cs) = M1 (K1 c) :*: context' b cs++instance {-# OVERLAPPABLE #-} (Context' g b) => Context' (f :*: g) b where+  context' (a :*: b) cs = a :*: context' b cs+++class Uniplate a where+  children :: a -> [a]+  default children :: (Generic a, Uniplate' (Rep a) a) => a -> [a]+  children = childrendefault++  context :: a -> [a] -> a+  default context :: (Generic a, Context' (Rep a) a) => a -> [a] -> a+  context = contextdefault++  descend :: (a -> a) -> a -> a+  default descend :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a+  descend = descenddefault++  descendM :: Monad m => (a -> m a) -> a -> m a+  default descendM :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a+  descendM = descendMdefault++  transform :: (a -> a) -> a -> a+  default transform :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a+  transform = transformdefault++  transformM :: Monad m => (a -> m a) -> a -> m a+  default transformM :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a+  transformM = transformMdefault++childrendefault :: (Generic a, Uniplate' (Rep a) a) => a -> [a]+childrendefault = children' . from++contextdefault :: (Generic a, Context' (Rep a) a) => a -> [a] -> a+contextdefault x cs = to (context' (from x) cs)++descenddefault :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a+descenddefault f = to . descend' f . from++descendMdefault :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a+descendMdefault f = liftM to . descendM' f . from++transformdefault :: (Generic a, Uniplate' (Rep a) a) => (a -> a) -> a -> a+transformdefault f = f . to . transform' f . from++transformMdefault :: (Generic a, Uniplate' (Rep a) a, Monad m) => (a -> m a) -> a -> m a+transformMdefault f = liftM to . transformM' f . from+++-- Derived functions (mostly copied from Neil Michell's code)++uniplate :: Uniplate a => a -> ([a], [a] -> a)+uniplate a = (children a, context a)++universe :: Uniplate a => a -> [a]+universe a = build (go a)+  where+    go x cons nil = cons x $ foldr ($) nil $ map (\c -> go c cons) $ children x++rewrite :: Uniplate a => (a -> Maybe a) -> a -> a+rewrite f = transform g+  where+    g x = maybe x (rewrite f) (f x)++rewriteM :: (Monad m, Uniplate a) => (a -> m (Maybe a)) -> a -> m a+rewriteM f = transformM g+  where+    g x = f x >>= maybe (return x) (rewriteM f)++contexts :: Uniplate a => a -> [(a, a -> a)]+contexts a = (a, id) : f (holes a)+  where+    f xs = [ (ch2, ctx1 . ctx2)+           | (ch1, ctx1) <- xs+           , (ch2, ctx2) <- contexts ch1]++holes :: Uniplate a => a -> [(a, a -> a)]+holes a = uncurry f (uniplate a)+  where+    f []     _   = []+    f (x:xs) gen = (x, gen . (:xs)) : f xs (gen . (x:))++para :: Uniplate a => (a -> [r] -> r) -> a -> r+para f x = f x $ map (para f) $ children x+++-- Base types instances+instance Uniplate Bool where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate Char where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate Double where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate Float where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate Int where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate () where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return++-- Tuple instances+instance Uniplate (b,c) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate (b,c,d) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate (b,c,d,e) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate (b,c,d,e,f) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate (b,c,d,e,f,g) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate (b,c,d,e,f,g,h) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return++-- Parameterized type instances+instance Uniplate (Maybe a) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return+instance Uniplate (Either a b) where+  children _ = []+  context x _ = x+  descend _ = id+  descendM _ = return+  transform = id+  transformM _ = return++instance Uniplate [a] where+  children []    = []+  children (_:t) = [t]+  context _     []    = error "Generics.Deriving.Uniplate.context: empty list"+  context []    _     = []+  context (h:_) (t:_) = h:t+  descend _ []    = []+  descend f (h:t) = h:f t+  descendM _ []    = return []+  descendM f (h:t) = f t >>= \t' -> return (h:t')+  transform f []    = f []+  transform f (h:t) = f (h:transform f t)+  transformM f []    = f []+  transformM f (h:t) = transformM f t >>= \t' -> f (h:t')+
+ tests/DefaultSpec.hs view
@@ -0,0 +1,161 @@+-- |+-- Module      : DefaultSpec+-- Description : Ensure that deriving via (Default a) newtype works+-- License     : BSD-3-Clause+--+-- Maintainer  : generics@haskell.org+-- Stability   : experimental+-- Portability : non-portable+--+-- Tests DerivingVia on GHC versions 8.6 and above. There are no tests on+-- versions below.+--+-- The test check a miscellany of properties of the derived type classes.+-- (Testing all the required properties is beyond the scope of this module.)+{-# LANGUAGE CPP #-}+#if __GLASGOW_HASKELL__ >= 806+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+#endif++module DefaultSpec where++import Test.Hspec++#if __GLASGOW_HASKELL__ >= 806+import Test.Hspec.QuickCheck++import Data.Semigroup (First(..))+import Data.Foldable (sequenceA_)+import Generics.Deriving hiding (universe)+import Generics.Deriving.Default ()+import Generics.Deriving.Foldable (GFoldable(..))+import Generics.Deriving.Semigroup (GSemigroup(..))+#endif++spec :: Spec+spec = do+  describe "DerivingVia Default" $ do++#if __GLASGOW_HASKELL__ >= 806+    it "GEq is commutative for derivingVia (Default MyType)" . sequenceA_ $+      let commutative :: GEq a => a -> a -> Expectation+          commutative x y = x `geq` y `shouldBe` y `geq` x++          universe :: [MyType]+          universe = MyType <$> [False, True]++      in  commutative <$> universe <*> universe++    it "GShow for MyType is like Show for Bool with derivingVia (Default MyType) but prefixed with 'MyType '" $ do+      gshowsPrec 0 (MyType False) "" `shouldBe` "MyType " <> showsPrec 0 False ""+      gshowsPrec 0 (MyType True) "" `shouldBe` "MyType " <> showsPrec 0 True ""++    it "GEq is commutative for parameterized derivingVia (Default (MyType1 Bool))" . sequenceA_ $+      let commutative :: GEq a => a -> a -> Expectation+          commutative x y = x `geq` y `shouldBe` y `geq` x++          universe :: [MyType1 Bool]+          universe = MyType1 <$> [False, True]++      in  commutative <$> universe <*> universe++    it "GShow for MyType1 Bool is like Show for Bool with derivingVia (Default (MyType1 Bool)) but prefixed with 'MyType1 '" $ do+      gshowsPrec 0 (MyType1 False) "" `shouldBe` "MyType1 " <> showsPrec 0 False ""+      gshowsPrec 0 (MyType1 True) "" `shouldBe` "MyType1 " <> showsPrec 0 True ""++    it "GEq is commutative for derivingVia (Default Bool)" . sequenceA_ $+      let commutative :: GEq a => a -> a -> Expectation+          commutative x y = x `geq` y `shouldBe` y `geq` x++          universe :: [TestEq]+          universe = TestEq <$> [False, True]++      in  commutative <$> universe <*> universe++    it "GENum is correct for derivingVia (Default Bool)" $+      genum `shouldBe` [TestEnum False, TestEnum True]++    it "GShow for TestShow is the same as Show for Bool with derivingVia (Default Bool)" $ do+      gshowsPrec 0 (TestShow False) "" `shouldBe` showsPrec 0 False ""+      gshowsPrec 0 (TestShow True) "" `shouldBe` showsPrec 0 True ""++    it "GSemigroup is like First when instantiated with derivingVia (First Bool)" . sequenceA_ $+      let first' :: (Eq a, Show a, GSemigroup a) => a -> a -> Expectation+          first' x y = x `gsappend` y `shouldBe` x++          universe :: [FirstSemigroup]+          universe = FirstSemigroup <$> [False, True]++      in  first' <$> universe <*> universe++    prop "GFoldable with derivingVia (Default1 Option) acts like mconcat with Maybe (First Bool)" $ \(xs :: [Maybe Bool]) ->+      let ys :: [Maybe (First Bool)]+          -- Note that there is no Arbitrary instance for this type+          ys = fmap First <$> xs++          unTestFoldable :: TestFoldable a -> Maybe a+          unTestFoldable (TestFoldable x) = x++      in  gfoldMap unTestFoldable (TestFoldable <$> ys) `shouldBe` mconcat ys++    it "GFunctor for TestFunctor Bool is as Functor for Maybe Bool" . sequenceA_ $+      let universe :: [Maybe Bool]+          universe = [Nothing, Just False, Just True]++          functor_prop :: Maybe Bool -> Expectation+          functor_prop x = gmap not (TestFunctor x) `shouldBe` TestFunctor (not <$> x)++      in  functor_prop <$> universe++#endif+    return ()++#if __GLASGOW_HASKELL__ >= 806++-- These types all implement instances using `DerivingVia`: most via+-- `Default` (one uses `First`).++newtype TestEq = TestEq Bool+  deriving (GEq) via (Default Bool)+newtype TestEnum = TestEnum Bool+  deriving stock (Eq, Show)+  deriving (GEnum) via (Default Bool)+newtype TestShow = TestShow Bool+  deriving (GShow) via (Default Bool)++newtype FirstSemigroup = FirstSemigroup Bool+  deriving stock (Eq, Show)+  deriving (GSemigroup) via (First Bool)++newtype TestFoldable a = TestFoldable (Maybe a)+  deriving (GFoldable) via (Default1 Maybe)++newtype TestFunctor a = TestFunctor (Maybe a)+  deriving stock (Eq, Show, Functor)+  deriving (GFunctor) via (Default1 Maybe)++newtype TestHigherEq a = TestHigherEq (Maybe a)+  deriving stock (Generic)+  deriving (GEq) via (Default (TestHigherEq a))++-- These types correspond to the hypothetical examples in the module+-- documentation.++data MyType = MyType Bool+  deriving (Generic)+  deriving (GEq) via (Default MyType)++deriving via (Default MyType) instance GShow MyType++data MyType1 a = MyType1 a+  deriving (Generic, Generic1)+  deriving (GEq) via (Default (MyType1 a))+  deriving (GFunctor) via (Default1 MyType1)++deriving via Default (MyType1 a) instance GShow a => GShow (MyType1 a)+deriving via (Default1 MyType1) instance GFoldable MyType1+#endif
+ tests/EmptyCaseSpec.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE EmptyCase #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}++module EmptyCaseSpec (main, spec) where++import Generics.Deriving.TH+import Test.Hspec++data Empty a+$(deriveAll0And1Options defaultOptions{emptyCaseOptions = True}+                        ''Empty)++main :: IO ()+main = hspec spec++spec :: Spec+spec = return ()
+ tests/ExampleSpec.hs view
@@ -0,0 +1,393 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module ExampleSpec (main, spec) where++import           Generics.Deriving+import           Generics.Deriving.TH++import           GHC.Exts (Addr#, Char#, Double#, Float#, Int#, Word#)++import           Prelude hiding (Either(..))++import           Test.Hspec (Spec, describe, hspec, it, parallel, shouldBe)++import qualified Text.Read.Lex (Lexeme)++-------------------------------------------------------------------------------+-- Example: Haskell's lists and Maybe+-------------------------------------------------------------------------------++hList:: [Int]+hList = [1..10]++maybe1, maybe2 :: Maybe (Maybe Char)+maybe1 = Nothing+maybe2 = Just (Just 'p')++double :: [Int] -> [Int]+double []     = []+double (x:xs) = x:x:xs++-------------------------------------------------------------------------------+-- Example: trees of integers (kind *)+-------------------------------------------------------------------------------++data Tree = Empty | Branch Int Tree Tree++$(deriveAll0 ''Tree)++instance GShow Tree where+    gshowsPrec = gshowsPrecdefault++instance Uniplate Tree where+  children   = childrendefault+  context    = contextdefault+  descend    = descenddefault+  descendM   = descendMdefault+  transform  = transformdefault+  transformM = transformMdefault++instance GEnum Tree where+    genum = genumDefault++upgradeTree :: Tree -> Tree+upgradeTree Empty          = Branch 0 Empty Empty+upgradeTree (Branch n l r) = Branch (succ n) l r++tree :: Tree+tree = Branch 2 Empty (Branch 1 Empty Empty)++-------------------------------------------------------------------------------+-- Example: lists (kind * -> *)+-------------------------------------------------------------------------------++data List a = Nil | Cons a (List a)++$(deriveAll0And1 ''List)++instance GFunctor List where+  gmap = gmapdefault++instance (GShow a) => GShow (List a) where+  gshowsPrec = gshowsPrecdefault++instance (Uniplate a) => Uniplate (List a) where+  children   = childrendefault+  context    = contextdefault+  descend    = descenddefault+  descendM   = descendMdefault+  transform  = transformdefault+  transformM = transformMdefault++list :: List Char+list = Cons 'p' (Cons 'q' Nil)++listlist :: List (List Char)+listlist = Cons list (Cons Nil Nil) -- ["pq",""]++-------------------------------------------------------------------------------+-- Example: Type composition+-------------------------------------------------------------------------------++data Rose a = Rose [a] [Rose a]++$(deriveAll0And1 ''Rose)++instance (GShow a) => GShow (Rose a) where+  gshowsPrec = gshowsPrecdefault++instance GFunctor Rose where+  gmap = gmapdefault++-- Example usage+rose1 :: Rose Int+rose1 = Rose [1,2] [Rose [3,4] [], Rose [5] []]++-------------------------------------------------------------------------------+-- Example: Higher-order kinded datatype, type composition+-------------------------------------------------------------------------------++data GRose f a = GRose (f a) (f (GRose f a))+deriving instance Functor f => Functor (GRose f)++$(deriveMeta           ''GRose)+$(deriveRepresentable0 ''GRose)+$(deriveRep1           ''GRose)+instance Functor f => Generic1 (GRose f) where+  type Rep1 (GRose f) = $(makeRep1 ''GRose) f+  from1 = $(makeFrom1 ''GRose)+  to1   = $(makeTo1 ''GRose)++instance (GShow (f a), GShow (f (GRose f a))) => GShow (GRose f a) where+  gshowsPrec = gshowsPrecdefault++instance (Functor f, GFunctor f) => GFunctor (GRose f) where+  gmap = gmapdefault++grose1 :: GRose [] Int+grose1 = GRose [1,2] [GRose [3] [], GRose [] []]++-------------------------------------------------------------------------------+-- Example: Two parameters, nested on other parameter+-------------------------------------------------------------------------------++data Either a b = Left (Either [a] b) | Right b++$(deriveAll0And1 ''Either)++instance (GShow a, GShow b) => GShow (Either a b) where+  gshowsPrec = gshowsPrecdefault++instance GFunctor (Either a) where+  gmap = gmapdefault++either1 :: Either Int Char+either1 = Left either2++either2 :: Either [Int] Char+either2 = Right 'p'++-------------------------------------------------------------------------------+-- Example: Nested datatype, record selectors+-------------------------------------------------------------------------------++data Nested a = Leaf | Nested { value :: a, rec :: Nested [a] }+  deriving Functor++$(deriveAll0And1 ''Nested)++instance (GShow a) => GShow (Nested a) where+  gshowsPrec = gshowsPrecdefault++instance GFunctor Nested where+  gmap = gmapdefault++nested :: Nested Int+nested = Nested { value = 1, rec = Nested [2] (Nested [[3],[4,5],[]] Leaf) }++-------------------------------------------------------------------------------+-- Example: Nested datatype Bush (minimal)+-------------------------------------------------------------------------------++data Bush a = BushNil | BushCons a (Bush (Bush a)) deriving Functor++$(deriveAll0And1 ''Bush)++instance GFunctor Bush where+  gmap = gmapdefault++instance (GShow a) => GShow (Bush a) where+  gshowsPrec = gshowsPrecdefault++bush1 :: Bush Int+bush1 = BushCons 0 (BushCons (BushCons 1 BushNil) BushNil)++-------------------------------------------------------------------------------+-- Example: Double type composition (minimal)+-------------------------------------------------------------------------------++data Weird a = Weird [[[a]]] deriving Show++$(deriveAll0And1 ''Weird)++instance GFunctor Weird where+  gmap = gmapdefault++--------------------------------------------------------------------------------+-- Temporary tests for TH generation+--------------------------------------------------------------------------------++data Empty a++data (:/:) f a = MyType1Nil+               | MyType1Cons { _myType1Rec :: (f :/: a), _myType2Rec :: MyType2 }+               | MyType1Cons2 (f :/: a) Int a (f a)+               | (f :/: a) :/: MyType2++infixr 5 :!@!:+data GADTSyntax a b where+  GADTPrefix :: d -> c -> GADTSyntax c d+  (:!@!:)    :: e -> f -> GADTSyntax e f++data MyType2 = MyType2 Float ([] :/: Int)+data PlainHash a = Hash a Addr# Char# Double# Float# Int# Word#++-- Test to see if generated names are unique+data Lexeme = Lexeme++data family MyType3 (a :: v) (b :: w) (c :: x) (d :: y) (e :: z)+newtype instance MyType3 (f p) (f p) f p (q :: *) = MyType3Newtype q+data    instance MyType3 Bool  ()    f p q        = MyType3True | MyType3False+data    instance MyType3 Int   ()    f p (q :: *) = MyType3Hash q Addr# Char# Double# Float# Int# Word#++$(deriveAll0And1 ''Empty)+$(deriveAll0And1 ''(:/:))+$(deriveAll0And1 ''GADTSyntax)+$(deriveAll0     ''MyType2)+$(deriveAll0And1 ''PlainHash)+$(deriveAll0     ''ExampleSpec.Lexeme)+$(deriveAll0     ''Text.Read.Lex.Lexeme)++$(deriveAll0And1 'MyType3Newtype)+$(deriveAll0And1 'MyType3False)+$(deriveAll0And1 'MyType3Hash)++-------------------------------------------------------------------------------+-- Unit tests+-------------------------------------------------------------------------------++main :: IO ()+main = hspec spec++spec :: Spec+spec = parallel $ do+    describe "[] and Maybe tests" $ do+        it "gshow hList" $+            gshow hList `shouldBe`+                "[1,2,3,4,5,6,7,8,9,10]"++        it "gshow (children maybe2)" $+            gshow (children maybe2) `shouldBe`+                "[]"++        it "gshow (transform (const \"abc\") [])" $+            gshow (transform (const "abc") []) `shouldBe`+                "\"abc\""++        it "gshow (transform double hList)" $+            gshow (transform double hList) `shouldBe`+                "[1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10]"++        it "gshow (geq hList hList)" $+            gshow (geq hList hList) `shouldBe`+                "True"++        it "gshow (geq maybe1 maybe2)" $+            gshow (geq maybe1 maybe2) `shouldBe`+                "False"++        it "gshow (take 5 genum)" $+            gshow (take 5 (genum :: [Maybe Int])) `shouldBe`+                "[Nothing,Just 0,Just -1,Just 1,Just -2]"++        it "gshow (take 15 genum)" $+            gshow (take 15 (genum :: [[Int]])) `shouldBe`+                "[[],[0],[0,0],[-1],[0,0,0],[-1,0],[1],[0,-1],[-1,0,0],[1,0],[-2],[0,0,0,0],[-1,-1],[1,0,0],[-2,0]]"++        it "gshow (range ([0], [1]))" $+            gshow (range ([0], [1::Int])) `shouldBe`+                "[[0],[0,0],[-1],[0,0,0],[-1,0]]"++        it "gshow (inRange ([0], [3,5]) hList)" $+            gshow (inRange ([0], [3,5::Int]) hList) `shouldBe`+                "False"++    describe "Tests for Tree" $ do+        it "gshow tree" $+            gshow tree `shouldBe`+                "Branch 2 Empty (Branch 1 Empty Empty)"++        it "gshow (children tree)" $+            gshow (children tree) `shouldBe`+                "[Empty,Branch 1 Empty Empty]"++        it "gshow (descend (descend (\\_ -> Branch 0 Empty Empty)) tree)" $+            gshow (descend (descend (\_ -> Branch 0 Empty Empty)) tree) `shouldBe`+                "Branch 2 Empty (Branch 1 (Branch 0 Empty Empty) (Branch 0 Empty Empty))"++        it "gshow (context tree [Branch 1 Empty Empty,Empty])" $+            gshow (context tree [Branch 1 Empty Empty,Empty]) `shouldBe`+                "Branch 2 (Branch 1 Empty Empty) Empty"++        it "gshow (transform upgradeTree tree)" $+            gshow (transform upgradeTree tree) `shouldBe`+                "Branch 3 (Branch 0 Empty Empty) (Branch 2 (Branch 0 Empty Empty) (Branch 0 Empty Empty))"++        it "gshow (take 10 genum)" $ do+            gshow (take 10 (genum :: [Tree])) `shouldBe`+                "[Empty,Branch 0 Empty Empty,Branch 0 Empty (Branch 0 Empty Empty),Branch -1 Empty Empty,Branch 0 (Branch 0 Empty Empty) Empty,Branch -1 Empty (Branch 0 Empty Empty),Branch 1 Empty Empty,Branch 0 Empty (Branch 0 Empty (Branch 0 Empty Empty)),Branch -1 (Branch 0 Empty Empty) Empty,Branch 1 Empty (Branch 0 Empty Empty)]"++    describe "Tests for List" $ do+        it "gshow (gmap fromEnum list)" $+            gshow (gmap fromEnum list) `shouldBe`+                "Cons 112 (Cons 113 Nil)"++        it "gshow (gmap gshow listlist)" $+            gshow (gmap gshow listlist) `shouldBe`+                "Cons \"Cons 'p' (Cons 'q' Nil)\" (Cons \"Nil\" Nil)"++        it "gshow list" $+            gshow list `shouldBe`+                "Cons 'p' (Cons 'q' Nil)"++        it "gshow listlist" $+            gshow listlist `shouldBe`+                "Cons (Cons 'p' (Cons 'q' Nil)) (Cons Nil Nil)"++        it "gshow (children list)" $+            gshow (children list) `shouldBe`+                "[Cons 'q' Nil]"++        it "gshow (children listlist)" $+            gshow (children listlist) `shouldBe`+                "[Cons Nil Nil]"++    describe "Tests for Rose" $ do+        it "gshow rose1" $+            gshow rose1 `shouldBe`+                "Rose [1,2] [Rose [3,4] [],Rose [5] []]"++        it "gshow (gmap gshow rose1)" $+            gshow (gmap gshow rose1) `shouldBe`+                "Rose [\"1\",\"2\"] [Rose [\"3\",\"4\"] [],Rose [\"5\"] []]"++    describe "Tests for GRose" $ do+        it "gshow grose1" $+            gshow grose1 `shouldBe`+                "GRose [1,2] [GRose [3] [],GRose [] []]"++        it "gshow (gmap gshow grose1)" $+            gshow (gmap gshow grose1) `shouldBe`+                "GRose [\"1\",\"2\"] [GRose [\"3\"] [],GRose [] []]"++    describe "Tests for Either" $ do+        it "gshow either1" $+            gshow either1 `shouldBe`+                "Left Right 'p'"++        it "gshow (gmap gshow either1)" $+            gshow (gmap gshow either1) `shouldBe`+                "Left Right \"'p'\""++    describe "Tests for Nested" $ do+        it "gshow nested" $+            gshow nested `shouldBe`+                "Nested {value = 1, rec = Nested {value = [2], rec = Nested {value = [[3],[4,5],[]], rec = Leaf}}}"++        it "gshow (gmap gshow nested)" $+            gshow (gmap gshow nested) `shouldBe`+                "Nested {value = \"1\", rec = Nested {value = [\"2\"], rec = Nested {value = [[\"3\"],[\"4\",\"5\"],[]], rec = Leaf}}}"++    describe "Tests for Bush" $ do+        it "gshow bush1" $+            gshow bush1 `shouldBe`+                "BushCons 0 (BushCons (BushCons 1 BushNil) BushNil)"++        it "gshow (gmap gshow bush1)" $+            gshow (gmap gshow bush1) `shouldBe`+                "BushCons \"0\" (BushCons (BushCons \"1\" BushNil) BushNil)"
+ tests/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ tests/T68Spec.hs view
@@ -0,0 +1,19 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}++module T68Spec (main, spec) where++import Generics.Deriving.TH+import Test.Hspec++main :: IO ()+main = hspec spec++spec :: Spec+spec = return ()++type family F68 :: * -> *+type instance F68 = Maybe+data T68 a = MkT68 (F68 a)+$(deriveAll1 ''T68)
+ tests/T80Spec.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}++module T80Spec (main, spec) where++import Generics.Deriving.TH+import Test.Hspec++main :: IO ()+main = hspec spec++spec :: Spec+spec = return ()++newtype T f a b = MkT (f a b)+$(deriveAll1 ''T)
+ tests/T82Spec.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}++#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++module T82Spec (main, spec) where++import Test.Hspec++#if MIN_VERSION_base(4,10,0)+import Generics.Deriving.TH+import GHC.Exts (RuntimeRep, TYPE)++data Code m (a :: TYPE (r :: RuntimeRep)) = Code+$(deriveAll0And1 ''Code)+#endif++main :: IO ()+main = hspec spec++spec :: Spec+spec = return ()
+ tests/TypeInTypeSpec.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}++#if __GLASGOW_HASKELL__ < 806+{-# LANGUAGE TypeInType #-}+#endif++module TypeInTypeSpec (main, spec) where++import Data.Proxy (Proxy(..))+import Generics.Deriving.TH+import Test.Hspec++#if MIN_VERSION_base(4,10,0)+import Generics.Deriving (Generic1(..))+#endif++data TyCon x (a :: x) (b :: k) = TyCon k x (Proxy a) (TyCon x a b)+$(deriveAll0And1 ''TyCon)++data family TyFam x (a :: x) (b :: k)+data instance TyFam x (a :: x) (b :: k) = TyFam k x (Proxy a) (TyFam x a b)+$(deriveAll0And1 'TyFam)++#if MIN_VERSION_base(4,10,0)+gen1PolyKinds :: Generic1 f => f 'True -> Rep1 f 'True+gen1PolyKinds = from1+#endif++main :: IO ()+main = hspec spec++spec :: Spec+spec = parallel $ do+#if MIN_VERSION_base(4,10,0)+    describe "TyCon Bool 'False 'True" $+      it "has an appropriately kinded Generic1 instance" $+        let rep :: Rep1 (TyCon Bool 'False) 'True+            rep = gen1PolyKinds $ let x = TyCon True False Proxy x in x+         in seq rep () `shouldBe` ()+    describe "TyFam Bool 'False 'True" $+      it "has an appropriately kinded Generic1 instance" $+        let rep :: Rep1 (TyFam Bool 'False) 'True+            rep = gen1PolyKinds $ let x = TyFam True False Proxy x in x+         in seq rep () `shouldBe` ()+#else+    return ()+#endif