{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}

#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE DefaultSignatures #-}
#endif

#if __GLASGOW_HASKELL__ >= 705
{-# LANGUAGE PolyKinds #-}
#endif

#if __GLASGOW_HASKELL__ >= 710
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif

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.Monoid
import Generics.Deriving.Base
import Generics.Deriving.Semigroup.Internal

#if MIN_VERSION_base(4,6,0)
import Data.Ord (Down)
#else
import GHC.Exts (Down)
#endif

#if MIN_VERSION_base(4,7,0)
import Data.Proxy (Proxy)
#endif

#if MIN_VERSION_base(4,8,0)
import Data.Functor.Identity (Identity)
#endif

--------------------------------------------------------------------------------

class GSemigroup' f => GMonoid' f where
  gmempty'  :: f x
  gmappend' :: f x -> f x -> f x

instance GMonoid' U1 where
  gmempty' :: U1 x
gmempty' = U1 x
forall k (x :: k). U1 x
U1
  gmappend' :: U1 x -> U1 x -> U1 x
gmappend' U1 x
U1 U1 x
U1 = U1 x
forall k (x :: k). U1 x
U1

instance GMonoid a => GMonoid' (K1 i a) where
  gmempty' :: K1 i a x
gmempty' = a -> K1 i a x
forall k i c (p :: k). c -> K1 i c p
K1 a
forall a. GMonoid a => a
gmempty
  gmappend' :: K1 i a x -> K1 i a x -> K1 i a x
gmappend' (K1 a
x) (K1 a
y) = a -> K1 i a x
forall k i c (p :: k). c -> K1 i c p
K1 (a
x a -> a -> a
forall a. GMonoid a => a -> a -> a
`gmappend` a
y)

instance GMonoid' f => GMonoid' (M1 i c f) where
  gmempty' :: M1 i c f x
gmempty' = f x -> M1 i c f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 f x
forall k (f :: k -> *) (x :: k). GMonoid' f => f x
gmempty'
  gmappend' :: M1 i c f x -> M1 i c f x -> M1 i c f x
gmappend' (M1 f x
x) (M1 f x
y) = f x -> M1 i c f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f x
x f x -> f x -> f x
forall k (f :: k -> *) (x :: k). GMonoid' f => f x -> f x -> f x
`gmappend'` f x
y)

instance (GMonoid' f, GMonoid' h) => GMonoid' (f :*: h) where
  gmempty' :: (:*:) f h x
gmempty' = f x
forall k (f :: k -> *) (x :: k). GMonoid' f => f x
gmempty' f x -> h x -> (:*:) f h x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: h x
forall k (f :: k -> *) (x :: k). GMonoid' f => f x
gmempty'
  gmappend' :: (:*:) f h x -> (:*:) f h x -> (:*:) f h x
gmappend' (f x
x1 :*: h x
y1) (f x
x2 :*: h x
y2) = f x -> f x -> f x
forall k (f :: k -> *) (x :: k). GMonoid' f => f x -> f x -> f x
gmappend' f x
x1 f x
x2 f x -> h x -> (:*:) f h x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: h x -> h x -> h x
forall k (f :: k -> *) (x :: k). GMonoid' f => f x -> f x -> f x
gmappend' h x
y1 h x
y2

--------------------------------------------------------------------------------

gmemptydefault :: (Generic a, GMonoid' (Rep a)) => a
gmemptydefault :: a
gmemptydefault = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
to Rep a Any
forall k (f :: k -> *) (x :: k). GMonoid' f => f x
gmempty'

gmappenddefault :: (Generic a, GMonoid' (Rep a)) => a -> a -> a
gmappenddefault :: a -> a -> a
gmappenddefault a
x a
y = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
to (Rep a Any -> Rep a Any -> Rep a Any
forall k (f :: k -> *) (x :: k). GMonoid' f => f x -> f x -> f x
gmappend' (a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from a
x) (a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from a
y))

--------------------------------------------------------------------------------

class Monoid' f where
  mempty'  :: f x
  mappend' :: f x -> f x -> f x

instance Monoid' U1 where
  mempty' :: U1 x
mempty' = U1 x
forall k (x :: k). U1 x
U1
  mappend' :: U1 x -> U1 x -> U1 x
mappend' U1 x
U1 U1 x
U1 = U1 x
forall k (x :: k). U1 x
U1

instance Monoid a => Monoid' (K1 i a) where
  mempty' :: K1 i a x
mempty' = a -> K1 i a x
forall k i c (p :: k). c -> K1 i c p
K1 a
forall a. Monoid a => a
mempty
  mappend' :: K1 i a x -> K1 i a x -> K1 i a x
mappend' (K1 a
x) (K1 a
y) = a -> K1 i a x
forall k i c (p :: k). c -> K1 i c p
K1 (a
x a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` a
y)

instance Monoid' f => Monoid' (M1 i c f) where
  mempty' :: M1 i c f x
mempty' = f x -> M1 i c f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 f x
forall k (f :: k -> *) (x :: k). Monoid' f => f x
mempty'
  mappend' :: M1 i c f x -> M1 i c f x -> M1 i c f x
mappend' (M1 f x
x) (M1 f x
y) = f x -> M1 i c f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f x
x f x -> f x -> f x
forall k (f :: k -> *) (x :: k). Monoid' f => f x -> f x -> f x
`mappend'` f x
y)

instance (Monoid' f, Monoid' h) => Monoid' (f :*: h) where
  mempty' :: (:*:) f h x
mempty' = f x
forall k (f :: k -> *) (x :: k). Monoid' f => f x
mempty' f x -> h x -> (:*:) f h x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: h x
forall k (f :: k -> *) (x :: k). Monoid' f => f x
mempty'
  mappend' :: (:*:) f h x -> (:*:) f h x -> (:*:) f h x
mappend' (f x
x1 :*: h x
y1) (f x
x2 :*: h x
y2) = f x -> f x -> f x
forall k (f :: k -> *) (x :: k). Monoid' f => f x -> f x -> f x
mappend' f x
x1 f x
x2 f x -> h x -> (:*:) f h x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: h x -> h x -> h x
forall k (f :: k -> *) (x :: k). Monoid' f => f x -> f x -> f x
mappend' h x
y1 h x
y2

--------------------------------------------------------------------------------

memptydefault :: (Generic a, Monoid' (Rep a)) => a
memptydefault :: a
memptydefault = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
to Rep a Any
forall k (f :: k -> *) (x :: k). Monoid' f => f x
mempty'

mappenddefault :: (Generic a, Monoid' (Rep a)) => a -> a -> a
mappenddefault :: a -> a -> a
mappenddefault a
x a
y = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
to (Rep a Any -> Rep a Any -> Rep a Any
forall k (f :: k -> *) (x :: k). Monoid' f => f x -> f x -> f x
mappend' (a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from a
x) (a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from a
y))

--------------------------------------------------------------------------------

class GSemigroup a => GMonoid a where

  -- | Generic 'mempty'
  gmempty  :: a

  -- | Generic 'mappend'
  gmappend :: a -> a -> a

  -- | Generic 'mconcat'
  gmconcat :: [a] -> a
  gmconcat = (a -> a -> a) -> a -> [a] -> a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
forall a. GMonoid a => a
gmempty

#if __GLASGOW_HASKELL__ >= 701
  default gmempty :: (Generic a, GMonoid' (Rep a)) => a
  gmempty = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
to Rep a Any
forall k (f :: k -> *) (x :: k). GMonoid' f => f x
gmempty'

  default gmappend :: (Generic a, GMonoid' (Rep a)) => a -> a -> a
  gmappend a
x a
y = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
to (Rep a Any -> Rep a Any -> Rep a Any
forall k (f :: k -> *) (x :: k). GMonoid' f => f x -> f x -> f x
gmappend' (a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from a
x) (a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from a
y))
#endif

--------------------------------------------------------------------------------

-- Instances that reuse Monoid
instance GMonoid Ordering where
  gmempty :: Ordering
gmempty = Ordering
forall a. Monoid a => a
mempty
  gmappend :: Ordering -> Ordering -> Ordering
gmappend = Ordering -> Ordering -> Ordering
forall a. Monoid a => a -> a -> a
mappend
instance GMonoid () where
  gmempty :: ()
gmempty = ()
forall a. Monoid a => a
mempty
  gmappend :: () -> () -> ()
gmappend = () -> () -> ()
forall a. Monoid a => a -> a -> a
mappend
instance GMonoid Any where
  gmempty :: Any
gmempty = Any
forall a. Monoid a => a
mempty
  gmappend :: Any -> Any -> Any
gmappend = Any -> Any -> Any
forall a. Monoid a => a -> a -> a
mappend
instance GMonoid All where
  gmempty :: All
gmempty = All
forall a. Monoid a => a
mempty
  gmappend :: All -> All -> All
gmappend = All -> All -> All
forall a. Monoid a => a -> a -> a
mappend
instance GMonoid (First a) where
  gmempty :: First a
gmempty = First a
forall a. Monoid a => a
mempty
  gmappend :: First a -> First a -> First a
gmappend = First a -> First a -> First a
forall a. Monoid a => a -> a -> a
mappend
instance GMonoid (Last a) where
  gmempty :: Last a
gmempty = Last a
forall a. Monoid a => a
mempty
  gmappend :: Last a -> Last a -> Last a
gmappend = Last a -> Last a -> Last a
forall a. Monoid a => a -> a -> a
mappend
instance Num a => GMonoid (Sum a) where
  gmempty :: Sum a
gmempty = Sum a
forall a. Monoid a => a
mempty
  gmappend :: Sum a -> Sum a -> Sum a
gmappend = Sum a -> Sum a -> Sum a
forall a. Monoid a => a -> a -> a
mappend
instance Num a => GMonoid (Product a) where
  gmempty :: Product a
gmempty = Product a
forall a. Monoid a => a
mempty
  gmappend :: Product a -> Product a -> Product a
gmappend = Product a -> Product a -> Product a
forall a. Monoid a => a -> a -> a
mappend
instance GMonoid [a] where
  gmempty :: [a]
gmempty  = [a]
forall a. Monoid a => a
mempty
  gmappend :: [a] -> [a] -> [a]
gmappend = [a] -> [a] -> [a]
forall a. Monoid a => a -> a -> a
mappend
instance GMonoid (Endo a) where
  gmempty :: Endo a
gmempty = Endo a
forall a. Monoid a => a
mempty
  gmappend :: Endo a -> Endo a -> Endo a
gmappend = Endo a -> Endo a -> Endo a
forall a. Monoid a => a -> a -> a
mappend
#if MIN_VERSION_base(4,8,0)
instance Alternative f => GMonoid (Alt f a) where
  gmempty :: Alt f a
gmempty = Alt f a
forall a. Monoid a => a
mempty
  gmappend :: Alt f a -> Alt f a -> Alt f a
gmappend = Alt f a -> Alt f a -> Alt f a
forall a. Monoid a => a -> a -> a
mappend
#endif

-- Handwritten instances
instance GMonoid a => GMonoid (Dual a) where
  gmempty :: Dual a
gmempty = a -> Dual a
forall a. a -> Dual a
Dual a
forall a. GMonoid a => a
gmempty
  gmappend :: Dual a -> Dual a -> Dual a
gmappend (Dual a
x) (Dual a
y) = a -> Dual a
forall a. a -> Dual a
Dual (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
y a
x)
instance GMonoid b => GMonoid (a -> b) where
  gmempty :: a -> b
gmempty a
_ = b
forall a. GMonoid a => a
gmempty
  gmappend :: (a -> b) -> (a -> b) -> a -> b
gmappend a -> b
f a -> b
g a
x = b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend (a -> b
f a
x) (a -> b
g a
x)
instance GMonoid a => GMonoid (Const a b) where
  gmempty :: Const a b
gmempty  = Const a b
forall a. (Generic a, GMonoid' (Rep a)) => a
gmemptydefault
  gmappend :: Const a b -> Const a b -> Const a b
gmappend = Const a b -> Const a b -> Const a b
forall a. (Generic a, GMonoid' (Rep a)) => a -> a -> a
gmappenddefault
instance GMonoid a => GMonoid (Down a) where
  gmempty :: Down a
gmempty  = Down a
forall a. (Generic a, GMonoid' (Rep a)) => a
gmemptydefault
  gmappend :: Down a -> Down a -> Down a
gmappend = Down a -> Down a -> Down a
forall a. (Generic a, GMonoid' (Rep a)) => a -> a -> a
gmappenddefault

#if MIN_VERSION_base(4,7,0)
instance GMonoid
# if MIN_VERSION_base(4,9,0)
                 (Proxy s)
# else
                 (Proxy (s :: *))
# endif
                 where
  gmempty :: Proxy s
gmempty  = Proxy s
forall a. (Generic a, Monoid' (Rep a)) => a
memptydefault
  gmappend :: Proxy s -> Proxy s -> Proxy s
gmappend = Proxy s -> Proxy s -> Proxy s
forall a. (Generic a, Monoid' (Rep a)) => a -> a -> a
mappenddefault
#endif

#if MIN_VERSION_base(4,8,0)
instance GMonoid a => GMonoid (Identity a) where
  gmempty :: Identity a
gmempty  = Identity a
forall a. (Generic a, GMonoid' (Rep a)) => a
gmemptydefault
  gmappend :: Identity a -> Identity a -> Identity a
gmappend = Identity a -> Identity a -> Identity a
forall a. (Generic a, GMonoid' (Rep a)) => a -> a -> a
gmappenddefault
#endif

-- Tuple instances
instance (GMonoid a,GMonoid b) => GMonoid (a,b) where
  gmempty :: (a, b)
gmempty = (a
forall a. GMonoid a => a
gmempty,b
forall a. GMonoid a => a
gmempty)
  gmappend :: (a, b) -> (a, b) -> (a, b)
gmappend (a
a1,b
b1) (a
a2,b
b2) =
    (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
a1 a
a2,b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend b
b1 b
b2)
instance (GMonoid a,GMonoid b,GMonoid c) => GMonoid (a,b,c) where
  gmempty :: (a, b, c)
gmempty = (a
forall a. GMonoid a => a
gmempty,b
forall a. GMonoid a => a
gmempty,c
forall a. GMonoid a => a
gmempty)
  gmappend :: (a, b, c) -> (a, b, c) -> (a, b, c)
gmappend (a
a1,b
b1,c
c1) (a
a2,b
b2,c
c2) =
    (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
a1 a
a2,b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend b
b1 b
b2,c -> c -> c
forall a. GMonoid a => a -> a -> a
gmappend c
c1 c
c2)
instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d) => GMonoid (a,b,c,d) where
  gmempty :: (a, b, c, d)
gmempty = (a
forall a. GMonoid a => a
gmempty,b
forall a. GMonoid a => a
gmempty,c
forall a. GMonoid a => a
gmempty,d
forall a. GMonoid a => a
gmempty)
  gmappend :: (a, b, c, d) -> (a, b, c, d) -> (a, b, c, d)
gmappend (a
a1,b
b1,c
c1,d
d1) (a
a2,b
b2,c
c2,d
d2) =
    (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
a1 a
a2,b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend b
b1 b
b2,c -> c -> c
forall a. GMonoid a => a -> a -> a
gmappend c
c1 c
c2,d -> d -> d
forall a. GMonoid a => a -> a -> a
gmappend d
d1 d
d2)
instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e) => GMonoid (a,b,c,d,e) where
  gmempty :: (a, b, c, d, e)
gmempty = (a
forall a. GMonoid a => a
gmempty,b
forall a. GMonoid a => a
gmempty,c
forall a. GMonoid a => a
gmempty,d
forall a. GMonoid a => a
gmempty,e
forall a. GMonoid a => a
gmempty)
  gmappend :: (a, b, c, d, e) -> (a, b, c, d, e) -> (a, b, c, d, e)
gmappend (a
a1,b
b1,c
c1,d
d1,e
e1) (a
a2,b
b2,c
c2,d
d2,e
e2) =
    (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
a1 a
a2,b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend b
b1 b
b2,c -> c -> c
forall a. GMonoid a => a -> a -> a
gmappend c
c1 c
c2,d -> d -> d
forall a. GMonoid a => a -> a -> a
gmappend d
d1 d
d2,e -> e -> e
forall a. GMonoid a => a -> a -> a
gmappend e
e1 e
e2)
instance (GMonoid a,GMonoid b,GMonoid c,GMonoid d,GMonoid e,GMonoid f) => GMonoid (a,b,c,d,e,f) where
  gmempty :: (a, b, c, d, e, f)
gmempty = (a
forall a. GMonoid a => a
gmempty,b
forall a. GMonoid a => a
gmempty,c
forall a. GMonoid a => a
gmempty,d
forall a. GMonoid a => a
gmempty,e
forall a. GMonoid a => a
gmempty,f
forall a. GMonoid a => a
gmempty)
  gmappend :: (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> (a, b, c, d, e, f)
gmappend (a
a1,b
b1,c
c1,d
d1,e
e1,f
f1) (a
a2,b
b2,c
c2,d
d2,e
e2,f
f2) =
    (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
a1 a
a2,b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend b
b1 b
b2,c -> c -> c
forall a. GMonoid a => a -> a -> a
gmappend c
c1 c
c2,d -> d -> d
forall a. GMonoid a => a -> a -> a
gmappend d
d1 d
d2,e -> e -> e
forall a. GMonoid a => a -> a -> a
gmappend e
e1 e
e2,f -> f -> f
forall a. GMonoid a => a -> a -> a
gmappend f
f1 f
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 :: (a, b, c, d, e, f, g)
gmempty = (a
forall a. GMonoid a => a
gmempty,b
forall a. GMonoid a => a
gmempty,c
forall a. GMonoid a => a
gmempty,d
forall a. GMonoid a => a
gmempty,e
forall a. GMonoid a => a
gmempty,f
forall a. GMonoid a => a
gmempty,g
forall a. GMonoid a => a
gmempty)
  gmappend :: (a, b, c, d, e, f, g)
-> (a, b, c, d, e, f, g) -> (a, b, c, d, e, f, g)
gmappend (a
a1,b
b1,c
c1,d
d1,e
e1,f
f1,g
g1) (a
a2,b
b2,c
c2,d
d2,e
e2,f
f2,g
g2) =
    (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
a1 a
a2,b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend b
b1 b
b2,c -> c -> c
forall a. GMonoid a => a -> a -> a
gmappend c
c1 c
c2,d -> d -> d
forall a. GMonoid a => a -> a -> a
gmappend d
d1 d
d2,e -> e -> e
forall a. GMonoid a => a -> a -> a
gmappend e
e1 e
e2,f -> f -> f
forall a. GMonoid a => a -> a -> a
gmappend f
f1 f
f2,g -> g -> g
forall a. GMonoid a => a -> a -> a
gmappend g
g1 g
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 :: (a, b, c, d, e, f, g, h)
gmempty = (a
forall a. GMonoid a => a
gmempty,b
forall a. GMonoid a => a
gmempty,c
forall a. GMonoid a => a
gmempty,d
forall a. GMonoid a => a
gmempty,e
forall a. GMonoid a => a
gmempty,f
forall a. GMonoid a => a
gmempty,g
forall a. GMonoid a => a
gmempty,h
forall a. GMonoid a => a
gmempty)
  gmappend :: (a, b, c, d, e, f, g, h)
-> (a, b, c, d, e, f, g, h) -> (a, b, c, d, e, f, g, h)
gmappend (a
a1,b
b1,c
c1,d
d1,e
e1,f
f1,g
g1,h
h1) (a
a2,b
b2,c
c2,d
d2,e
e2,f
f2,g
g2,h
h2) =
    (a -> a -> a
forall a. GMonoid a => a -> a -> a
gmappend a
a1 a
a2,b -> b -> b
forall a. GMonoid a => a -> a -> a
gmappend b
b1 b
b2,c -> c -> c
forall a. GMonoid a => a -> a -> a
gmappend c
c1 c
c2,d -> d -> d
forall a. GMonoid a => a -> a -> a
gmappend d
d1 d
d2,e -> e -> e
forall a. GMonoid a => a -> a -> a
gmappend e
e1 e
e2,f -> f -> f
forall a. GMonoid a => a -> a -> a
gmappend f
f1 f
f2,g -> g -> g
forall a. GMonoid a => a -> a -> a
gmappend g
g1 g
g2,h -> h -> h
forall a. GMonoid a => a -> a -> a
gmappend h
h1 h
h2)