{-# LANGUAGE
  CPP,
  FlexibleContexts,
  TypeFamilies,
  UndecidableInstances,
  UndecidableSuperClasses #-}

-- | Newtypes with instances implemented using generic combinators.
--
-- === Warning
--
-- This is an internal module: it is not subject to any versioning policy,
-- breaking changes can happen at any time.
--
-- If something here seems useful, please report it or create a pull request to
-- export it from an external module.

module Generic.Data.Internal.Generically where

import Control.Applicative
import Data.Functor.Classes
import Data.Semigroup
import Data.Ix
import GHC.Generics
import Text.Read

import Generic.Data.Internal.Prelude hiding (gfoldMap, gtraverse, gsequenceA)
import Generic.Data.Internal.Enum
import Generic.Data.Internal.Error
import Generic.Data.Internal.Read
import Generic.Data.Internal.Show
import Generic.Data.Internal.Traversable (GFoldable, GTraversable, gfoldMap, gtraverse, gsequenceA)

-- $setup
-- >>> :set -XDerivingVia -XDeriveGeneric
-- >>> import GHC.Generics (Generic, Generic1)

-- | Type with instances derived via 'Generic'.
--
-- === Examples
--
-- ==== __Deriving 'Eq', 'Ord', 'Show', 'Read'__
--
-- >>> :{
-- data T = C Int Bool
--   deriving Generic
--   deriving (Eq, Ord, Show, Read) via (Generically T)
-- :}
--
-- ==== __Deriving 'Semigroup', 'Monoid'__
--
-- The type must have only one constructor.
--
-- >>> import Data.Monoid (Sum)
-- >>> :{
-- data U = D [Int] (Sum Int)
--   deriving Generic
--   deriving (Semigroup, Monoid) via (Generically U)
-- :}
--
-- ==== __Deriving 'Enum', 'Bounded'__
--
-- The type must have only nullary constructors.
-- To lift that restriction, see 'FiniteEnumeration'.
--
-- >>> :{
-- data V = X | Y | Z
--   deriving Generic
--   deriving (Eq, Ord, Enum, Bounded) via (Generically V)
-- :}
newtype Generically a = Generically { Generically a -> a
unGenerically :: a }

instance Generic a => Generic (Generically a) where
  type Rep (Generically a) = Rep a
  to :: Rep (Generically a) x -> Generically a
to = a -> Generically a
forall a. a -> Generically a
Generically (a -> Generically a) -> (Rep a x -> a) -> Rep a x -> Generically a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep a x -> a
forall a x. Generic a => Rep a x -> a
to
  from :: Generically a -> Rep (Generically a) x
from = a -> Rep a x
forall a x. Generic a => a -> Rep a x
from (a -> Rep a x) -> (Generically a -> a) -> Generically a -> Rep a x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Generically a -> a
forall a. Generically a -> a
unGenerically

instance (Generic a, Eq (Rep a ())) => Eq (Generically a) where
  == :: Generically a -> Generically a -> Bool
(==) = Generically a -> Generically a -> Bool
forall a. (Generic a, Eq (Rep a ())) => a -> a -> Bool
geq

instance (Generic a, Ord (Rep a ())) => Ord (Generically a) where
  compare :: Generically a -> Generically a -> Ordering
compare = Generically a -> Generically a -> Ordering
forall a. (Generic a, Ord (Rep a ())) => a -> a -> Ordering
gcompare

instance (Generic a, GRead0 (Rep a)) => Read (Generically a) where
  readPrec :: ReadPrec (Generically a)
readPrec = ReadPrec (Generically a)
forall a. (Generic a, GRead0 (Rep a)) => ReadPrec a
greadPrec
  readListPrec :: ReadPrec [Generically a]
readListPrec = ReadPrec [Generically a]
forall a. Read a => ReadPrec [a]
readListPrecDefault

instance (Generic a, GShow0 (Rep a)) => Show (Generically a) where
  showsPrec :: Int -> Generically a -> ShowS
showsPrec = Int -> Generically a -> ShowS
forall a. (Generic a, GShow0 (Rep a)) => Int -> a -> ShowS
gshowsPrec

instance (AssertNoSum Semigroup a, Generic a, Semigroup (Rep a ())) => Semigroup (Generically a) where
  <> :: Generically a -> Generically a -> Generically a
(<>) = Generically a -> Generically a -> Generically a
forall a. (Generic a, Semigroup (Rep a ())) => a -> a -> a
gmappend

-- | This uses the 'Semigroup' instance of the wrapped type 'a' to define 'mappend'.
-- The purpose of this instance is to derive 'mempty', while remaining consistent
-- with possibly custom 'Semigroup' instances.
instance (AssertNoSum Semigroup a, Semigroup a, Generic a, Monoid (Rep a ())) => Monoid (Generically a) where
  mempty :: Generically a
mempty = Generically a
forall a. (Generic a, Monoid (Rep a ())) => a
gmempty
  mappend :: Generically a -> Generically a -> Generically a
mappend (Generically a
x) (Generically a
y) = a -> Generically a
forall a. a -> Generically a
Generically (a
x a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
y)

instance (Generic a, GEnum StandardEnum (Rep a)) => Enum (Generically a) where
  toEnum :: Int -> Generically a
toEnum = Int -> Generically a
forall a. (Generic a, GEnum StandardEnum (Rep a)) => Int -> a
gtoEnum
  fromEnum :: Generically a -> Int
fromEnum = Generically a -> Int
forall a. (Generic a, GEnum StandardEnum (Rep a)) => a -> Int
gfromEnum
  enumFrom :: Generically a -> [Generically a]
enumFrom = Generically a -> [Generically a]
forall a. (Generic a, GEnum StandardEnum (Rep a)) => a -> [a]
genumFrom
  enumFromThen :: Generically a -> Generically a -> [Generically a]
enumFromThen = Generically a -> Generically a -> [Generically a]
forall a. (Generic a, GEnum StandardEnum (Rep a)) => a -> a -> [a]
genumFromThen
  enumFromTo :: Generically a -> Generically a -> [Generically a]
enumFromTo = Generically a -> Generically a -> [Generically a]
forall a. (Generic a, GEnum StandardEnum (Rep a)) => a -> a -> [a]
genumFromTo
  enumFromThenTo :: Generically a -> Generically a -> Generically a -> [Generically a]
enumFromThenTo = Generically a -> Generically a -> Generically a -> [Generically a]
forall a.
(Generic a, GEnum StandardEnum (Rep a)) =>
a -> a -> a -> [a]
genumFromThenTo

instance (Generic a, Ord (Rep a ()), GIx (Rep a)) => Ix (Generically a) where
  range :: (Generically a, Generically a) -> [Generically a]
range = (Generically a, Generically a) -> [Generically a]
forall a. (Generic a, GIx (Rep a)) => (a, a) -> [a]
grange
  index :: (Generically a, Generically a) -> Generically a -> Int
index = (Generically a, Generically a) -> Generically a -> Int
forall a. (Generic a, GIx (Rep a)) => (a, a) -> a -> Int
gindex
  inRange :: (Generically a, Generically a) -> Generically a -> Bool
inRange = (Generically a, Generically a) -> Generically a -> Bool
forall a. (Generic a, GIx (Rep a)) => (a, a) -> a -> Bool
ginRange

instance (Generic a, GBounded (Rep a)) => Bounded (Generically a) where
  minBound :: Generically a
minBound = Generically a
forall a. (Generic a, GBounded (Rep a)) => a
gminBound
  maxBound :: Generically a
maxBound = Generically a
forall a. (Generic a, GBounded (Rep a)) => a
gmaxBound

-- | Type with 'Enum' instance derived via 'Generic' with 'FiniteEnum' option.
-- This allows deriving 'Enum' for types whose constructors have fields.
--
-- Some caution is advised; see details in 'FiniteEnum'.
--
-- === __Example__
--
-- >>> :{
-- data Booool = Booool Bool Bool
--   deriving Generic
--   deriving (Enum, Bounded) via (FiniteEnumeration Booool)
-- :}
newtype FiniteEnumeration a = FiniteEnumeration { FiniteEnumeration a -> a
unFiniteEnumeration :: a }

instance Generic a => Generic (FiniteEnumeration a) where
  type Rep (FiniteEnumeration a) = Rep a
  to :: Rep (FiniteEnumeration a) x -> FiniteEnumeration a
to = a -> FiniteEnumeration a
forall a. a -> FiniteEnumeration a
FiniteEnumeration (a -> FiniteEnumeration a)
-> (Rep a x -> a) -> Rep a x -> FiniteEnumeration a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep a x -> a
forall a x. Generic a => Rep a x -> a
to
  from :: FiniteEnumeration a -> Rep (FiniteEnumeration a) x
from = a -> Rep a x
forall a x. Generic a => a -> Rep a x
from (a -> Rep a x)
-> (FiniteEnumeration a -> a) -> FiniteEnumeration a -> Rep a x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FiniteEnumeration a -> a
forall a. FiniteEnumeration a -> a
unFiniteEnumeration

instance (Generic a, GEnum FiniteEnum (Rep a)) => Enum (FiniteEnumeration a) where
  toEnum :: Int -> FiniteEnumeration a
toEnum = Int -> FiniteEnumeration a
forall a. (Generic a, GEnum FiniteEnum (Rep a)) => Int -> a
gtoFiniteEnum
  fromEnum :: FiniteEnumeration a -> Int
fromEnum = FiniteEnumeration a -> Int
forall a. (Generic a, GEnum FiniteEnum (Rep a)) => a -> Int
gfromFiniteEnum
  enumFrom :: FiniteEnumeration a -> [FiniteEnumeration a]
enumFrom = FiniteEnumeration a -> [FiniteEnumeration a]
forall a. (Generic a, GEnum FiniteEnum (Rep a)) => a -> [a]
gfiniteEnumFrom
  enumFromThen :: FiniteEnumeration a -> FiniteEnumeration a -> [FiniteEnumeration a]
enumFromThen = FiniteEnumeration a -> FiniteEnumeration a -> [FiniteEnumeration a]
forall a. (Generic a, GEnum FiniteEnum (Rep a)) => a -> a -> [a]
gfiniteEnumFromThen
  enumFromTo :: FiniteEnumeration a -> FiniteEnumeration a -> [FiniteEnumeration a]
enumFromTo = FiniteEnumeration a -> FiniteEnumeration a -> [FiniteEnumeration a]
forall a. (Generic a, GEnum FiniteEnum (Rep a)) => a -> a -> [a]
gfiniteEnumFromTo
  enumFromThenTo :: FiniteEnumeration a
-> FiniteEnumeration a
-> FiniteEnumeration a
-> [FiniteEnumeration a]
enumFromThenTo = FiniteEnumeration a
-> FiniteEnumeration a
-> FiniteEnumeration a
-> [FiniteEnumeration a]
forall a.
(Generic a, GEnum FiniteEnum (Rep a)) =>
a -> a -> a -> [a]
gfiniteEnumFromThenTo

-- | The same instance as 'Generically', for convenience.
instance (Generic a, GBounded (Rep a)) => Bounded (FiniteEnumeration a) where
  minBound :: FiniteEnumeration a
minBound = FiniteEnumeration a
forall a. (Generic a, GBounded (Rep a)) => a
gminBound
  maxBound :: FiniteEnumeration a
maxBound = FiniteEnumeration a
forall a. (Generic a, GBounded (Rep a)) => a
gmaxBound

-- | Type with instances derived via 'Generic1'.
--
-- === Examples
--
-- ==== __Deriving 'Functor', 'Applicative', 'Alternative'__
--
-- 'Applicative' can be derived for types with only one
-- constructor, aka. products.
--
-- >>> :{
-- data F a = F1 a | F2 (Maybe a) | F3 [Either Bool a] (Int, a)
--   deriving Generic1
--   deriving Functor via (Generically1 F)
-- :}
--
-- >>> :{
-- data G a = G a (Maybe a) [a] (IO a)
--   deriving Generic1
--   deriving (Functor, Applicative) via (Generically1 G)
-- :}
--
-- >>> import Control.Applicative (Alternative)
-- >>> :{
-- data G' a = G' (Maybe a) [a]
--   deriving Generic1
--   deriving (Functor, Applicative, Alternative) via (Generically1 G')
-- :}
--
-- ==== __Deriving 'Foldable'__
--
-- >>> import Generic.Data.Orphans ()
-- >>> :{
-- data H a = H1 a | H2 (Maybe a)
--   deriving Generic1
--   deriving (Functor, Foldable) via (Generically1 H)
-- :}
--
-- Note: we can't use @DerivingVia@ for 'Traversable'.
-- One may implement 'Traversable' explicitly using 'gtraverse'.
--
-- ==== __Deriving 'Eq1', 'Ord1'__
--
-- >>> import Data.Functor.Classes (Eq1, Ord1)
-- >>> :{
-- data I a = I [a] (Maybe a)
--   deriving Generic1
--   deriving (Eq1, Ord1) via (Generically1 I)
-- :}
newtype Generically1 f a = Generically1 { Generically1 f a -> f a
unGenerically1 :: f a }

instance Generic (f a) => Generic (Generically1 f a) where
  type Rep (Generically1 f a) = Rep (f a)
  to :: Rep (Generically1 f a) x -> Generically1 f a
to = f a -> Generically1 f a
forall (f :: * -> *) a. f a -> Generically1 f a
Generically1 (f a -> Generically1 f a)
-> (Rep (f a) x -> f a) -> Rep (f a) x -> Generically1 f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep (f a) x -> f a
forall a x. Generic a => Rep a x -> a
to
  from :: Generically1 f a -> Rep (Generically1 f a) x
from = f a -> Rep (f a) x
forall a x. Generic a => a -> Rep a x
from (f a -> Rep (f a) x)
-> (Generically1 f a -> f a) -> Generically1 f a -> Rep (f a) x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Generically1 f a -> f a
forall (f :: * -> *) a. Generically1 f a -> f a
unGenerically1

instance Generic1 f => Generic1 (Generically1 f) where
  type Rep1 (Generically1 f) = Rep1 f
  to1 :: Rep1 (Generically1 f) a -> Generically1 f a
to1 = f a -> Generically1 f a
forall (f :: * -> *) a. f a -> Generically1 f a
Generically1 (f a -> Generically1 f a)
-> (Rep1 f a -> f a) -> Rep1 f a -> Generically1 f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep1 f a -> f a
forall k (f :: k -> *) (a :: k). Generic1 f => Rep1 f a -> f a
to1
  from1 :: Generically1 f a -> Rep1 (Generically1 f) a
from1 = f a -> Rep1 f a
forall k (f :: k -> *) (a :: k). Generic1 f => f a -> Rep1 f a
from1 (f a -> Rep1 f a)
-> (Generically1 f a -> f a) -> Generically1 f a -> Rep1 f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Generically1 f a -> f a
forall (f :: * -> *) a. Generically1 f a -> f a
unGenerically1

instance (Generic1 f, Eq1 (Rep1 f)) => Eq1 (Generically1 f) where
  liftEq :: (a -> b -> Bool) -> Generically1 f a -> Generically1 f b -> Bool
liftEq = (a -> b -> Bool) -> Generically1 f a -> Generically1 f b -> Bool
forall (f :: * -> *) a b.
(Generic1 f, Eq1 (Rep1 f)) =>
(a -> b -> Bool) -> f a -> f b -> Bool
gliftEq

instance (Generic1 f, Eq1 (Rep1 f), Eq a) => Eq (Generically1 f a) where
  == :: Generically1 f a -> Generically1 f a -> Bool
(==) = Generically1 f a -> Generically1 f a -> Bool
forall (f :: * -> *) a. (Eq1 f, Eq a) => f a -> f a -> Bool
eq1

instance (Generic1 f, Ord1 (Rep1 f)) => Ord1 (Generically1 f) where
  liftCompare :: (a -> b -> Ordering)
-> Generically1 f a -> Generically1 f b -> Ordering
liftCompare = (a -> b -> Ordering)
-> Generically1 f a -> Generically1 f b -> Ordering
forall (f :: * -> *) a b.
(Generic1 f, Ord1 (Rep1 f)) =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
gliftCompare

instance (Generic1 f, Ord1 (Rep1 f), Ord a) => Ord (Generically1 f a) where
  compare :: Generically1 f a -> Generically1 f a -> Ordering
compare = Generically1 f a -> Generically1 f a -> Ordering
forall (f :: * -> *) a. (Ord1 f, Ord a) => f a -> f a -> Ordering
compare1

instance (Generic1 f, GRead1 (Rep1 f)) => Read1 (Generically1 f) where
#if MIN_VERSION_base(4,10,0)
  liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (Generically1 f a)
liftReadPrec = ReadPrec a -> ReadPrec [a] -> ReadPrec (Generically1 f a)
forall (f :: * -> *) a.
(Generic1 f, GRead1 (Rep1 f)) =>
ReadPrec a -> ReadPrec [a] -> ReadPrec (f a)
gliftReadPrec
  liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [Generically1 f a]
liftReadListPrec = ReadPrec a -> ReadPrec [a] -> ReadPrec [Generically1 f a]
forall (f :: * -> *) a.
Read1 f =>
ReadPrec a -> ReadPrec [a] -> ReadPrec [f a]
liftReadListPrecDefault
#else
  liftReadsPrec rp rl = readPrec_to_S $
    gliftReadPrec (readS_to_Prec rp) (readS_to_Prec (const rl))
#endif

instance (Generic1 f, GRead1 (Rep1 f), Read a) => Read (Generically1 f a) where
#if MIN_VERSION_base(4,10,0)
  readPrec :: ReadPrec (Generically1 f a)
readPrec = ReadPrec (Generically1 f a)
forall (f :: * -> *) a. (Read1 f, Read a) => ReadPrec (f a)
readPrec1
  readListPrec :: ReadPrec [Generically1 f a]
readListPrec = ReadPrec [Generically1 f a]
forall a. Read a => ReadPrec [a]
readListPrecDefault
#else
  readsPrec = readsPrec1
#endif

instance (Generic1 f, GShow1 (Rep1 f)) => Show1 (Generically1 f) where
  liftShowsPrec :: (Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> Generically1 f a -> ShowS
liftShowsPrec = (Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> Generically1 f a -> ShowS
forall (f :: * -> *) a.
(Generic1 f, GShow1 (Rep1 f)) =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
gliftShowsPrec

instance (Generic1 f, GShow1 (Rep1 f), Show a) => Show (Generically1 f a) where
  showsPrec :: Int -> Generically1 f a -> ShowS
showsPrec = Int -> Generically1 f a -> ShowS
forall (f :: * -> *) a. (Show1 f, Show a) => Int -> f a -> ShowS
showsPrec1

instance (Generic1 f, Functor (Rep1 f)) => Functor (Generically1 f) where
  fmap :: (a -> b) -> Generically1 f a -> Generically1 f b
fmap = (a -> b) -> Generically1 f a -> Generically1 f b
forall (f :: * -> *) a b.
(Generic1 f, Functor (Rep1 f)) =>
(a -> b) -> f a -> f b
gfmap
  <$ :: a -> Generically1 f b -> Generically1 f a
(<$) = a -> Generically1 f b -> Generically1 f a
forall (f :: * -> *) a b.
(Generic1 f, Functor (Rep1 f)) =>
a -> f b -> f a
gconstmap

instance (Generic1 f, Applicative (Rep1 f)) => Applicative (Generically1 f) where
  pure :: a -> Generically1 f a
pure = a -> Generically1 f a
forall (f :: * -> *) a.
(Generic1 f, Applicative (Rep1 f)) =>
a -> f a
gpure
  <*> :: Generically1 f (a -> b) -> Generically1 f a -> Generically1 f b
(<*>) = Generically1 f (a -> b) -> Generically1 f a -> Generically1 f b
forall (f :: * -> *) a b.
(Generic1 f, Applicative (Rep1 f)) =>
f (a -> b) -> f a -> f b
gap
#if MIN_VERSION_base(4,10,0)
  liftA2 :: (a -> b -> c)
-> Generically1 f a -> Generically1 f b -> Generically1 f c
liftA2 = (a -> b -> c)
-> Generically1 f a -> Generically1 f b -> Generically1 f c
forall (f :: * -> *) a b c.
(Generic1 f, Applicative (Rep1 f)) =>
(a -> b -> c) -> f a -> f b -> f c
gliftA2
#endif

instance (Generic1 f, Alternative (Rep1 f)) => Alternative (Generically1 f) where
  empty :: Generically1 f a
empty = Generically1 f a
forall (f :: * -> *) a. (Generic1 f, Alternative (Rep1 f)) => f a
gempty
  <|> :: Generically1 f a -> Generically1 f a -> Generically1 f a
(<|>) = Generically1 f a -> Generically1 f a -> Generically1 f a
forall (f :: * -> *) a.
(Generic1 f, Alternative (Rep1 f)) =>
f a -> f a -> f a
galt

instance (Generic1 f, GFoldable (Rep1 f)) => Foldable (Generically1 f) where
  foldMap :: (a -> m) -> Generically1 f a -> m
foldMap = (a -> m) -> Generically1 f a -> m
forall (f :: * -> *) m a.
(Generic1 f, GFoldable (Rep1 f), Monoid m) =>
(a -> m) -> f a -> m
gfoldMap
  foldr :: (a -> b -> b) -> b -> Generically1 f a -> b
foldr = (a -> b -> b) -> b -> Generically1 f a -> b
forall (f :: * -> *) a b.
(Generic1 f, Foldable (Rep1 f)) =>
(a -> b -> b) -> b -> f a -> b
gfoldr

instance (Generic1 f, Functor (Rep1 f), GFoldable (Rep1 f), GTraversable (Rep1 f))
  => Traversable (Generically1 f) where
  traverse :: (a -> f b) -> Generically1 f a -> f (Generically1 f b)
traverse = (a -> f b) -> Generically1 f a -> f (Generically1 f b)
forall (f :: * -> *) (m :: * -> *) a b.
(Generic1 f, GTraversable (Rep1 f), Applicative m) =>
(a -> m b) -> f a -> m (f b)
gtraverse
  sequenceA :: Generically1 f (f a) -> f (Generically1 f a)
sequenceA = Generically1 f (f a) -> f (Generically1 f a)
forall (f :: * -> *) (m :: * -> *) a.
(Generic1 f, GTraversable (Rep1 f), Applicative m) =>
f (m a) -> m (f a)
gsequenceA


-- | Product type with generic instances of 'Semigroup' and 'Monoid'.
--
-- This is similar to 'Generic.Data.Generically' in most cases, but
-- 'GenericProduct' also works for types @T@ with deriving
-- @via 'GenericProduct' U@, where @U@ is a generic product type coercible to,
-- but distinct from @T@. In particular, @U@ may not have an instance of
-- 'Semigroup', which 'Generic.Data.Generically' requires.
--
-- === __Example__
--
-- >>> import Data.Monoid (Sum(..))
-- >>> data Point a = Point a a deriving Generic
-- >>> :{
--   newtype Vector a = Vector (Point a)
--     deriving (Semigroup, Monoid)
--       via GenericProduct (Point (Sum a))
-- :}
--
-- If it were @via 'Generic.Data.Generically' (Point (Sum a))@ instead, then
-- @Vector@'s 'mappend' (the 'Monoid' method) would be defined as @Point@'s
-- @('<>')@ (the 'Semigroup' method), which might not exist, or might not be
-- equivalent to @Vector@'s generic 'Semigroup' instance, which would be
-- unlawful.
newtype GenericProduct a = GenericProduct { GenericProduct a -> a
unGenericProduct :: a }

instance Generic a => Generic (GenericProduct a) where
  type Rep (GenericProduct a) = Rep a
  to :: Rep (GenericProduct a) x -> GenericProduct a
to = a -> GenericProduct a
forall a. a -> GenericProduct a
GenericProduct (a -> GenericProduct a)
-> (Rep a x -> a) -> Rep a x -> GenericProduct a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep a x -> a
forall a x. Generic a => Rep a x -> a
to
  from :: GenericProduct a -> Rep (GenericProduct a) x
from = a -> Rep a x
forall a x. Generic a => a -> Rep a x
from (a -> Rep a x)
-> (GenericProduct a -> a) -> GenericProduct a -> Rep a x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenericProduct a -> a
forall a. GenericProduct a -> a
unGenericProduct

instance (AssertNoSum Semigroup a, Generic a, Semigroup (Rep a ())) => Semigroup (GenericProduct a) where
  <> :: GenericProduct a -> GenericProduct a -> GenericProduct a
(<>) = GenericProduct a -> GenericProduct a -> GenericProduct a
forall a. (Generic a, Semigroup (Rep a ())) => a -> a -> a
gmappend

instance (AssertNoSum Semigroup a, Generic a, Monoid (Rep a ())) => Monoid (GenericProduct a) where
  mempty :: GenericProduct a
mempty = GenericProduct a
forall a. (Generic a, Monoid (Rep a ())) => a
gmempty
  mappend :: GenericProduct a -> GenericProduct a -> GenericProduct a
mappend = GenericProduct a -> GenericProduct a -> GenericProduct a
forall a. (Generic a, Monoid (Rep a ())) => a -> a -> a
gmappend'