{-# LANGUAGE DataKinds            #-}
{-# LANGUAGE EmptyCase            #-}
{-# LANGUAGE FlexibleContexts     #-}
{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE LambdaCase           #-}
{-# LANGUAGE TypeOperators        #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS -Wno-unticked-promoted-constructors #-}

-- | "GHC.Generics" definition of '<>'
module Data.DerivingVia.GHC.Generics.Semigroup
  ( GSemigroup (..)
  )
where

import GHC.Generics
import GHC.TypeLits

class GSemigroup rep where
  gsappend :: rep x -> rep x -> rep x

instance Monoid c => GSemigroup (K1 i c) where
  gsappend :: K1 i c x -> K1 i c x -> K1 i c x
gsappend (K1 c
l) (K1 c
r) = c -> K1 i c x
forall k i c (p :: k). c -> K1 i c p
K1 (c
l c -> c -> c
forall a. Semigroup a => a -> a -> a
<> c
r)

instance GSemigroup f => GSemigroup (M1 i c f) where
  gsappend :: M1 i c f x -> M1 i c f x -> M1 i c f x
gsappend (M1 f x
l) (M1 f x
r) = 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 -> f x -> f x
forall (rep :: * -> *) x. GSemigroup rep => rep x -> rep x -> rep x
gsappend f x
l f x
r)

instance GSemigroup V1 where
  gsappend :: V1 x -> V1 x -> V1 x
gsappend = \case {}

instance GSemigroup U1 where
  gsappend :: U1 x -> U1 x -> U1 x
gsappend U1 x
U1 U1 x
U1 = U1 x
forall k (p :: k). U1 p
U1

instance (GSemigroup l, GSemigroup r) => GSemigroup (l :*: r) where
  gsappend :: (:*:) l r x -> (:*:) l r x -> (:*:) l r x
gsappend (l x
l1 :*: r x
r1) (l x
l2 :*: r x
r2) = l x -> l x -> l x
forall (rep :: * -> *) x. GSemigroup rep => rep x -> rep x -> rep x
gsappend l x
l1 l x
l2 l x -> r x -> (:*:) l r x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: r x -> r x -> r x
forall (rep :: * -> *) x. GSemigroup rep => rep x -> rep x -> rep x
gsappend r x
r1 r x
r2

instance TypeError (     Text "No Generics definition of "
                    :<>: ShowType Semigroup
                    :<>: Text " for types with multiple constructors "
                    :<>: ShowType (l :+: r)
                   )
      => GSemigroup (l :+: r) where
  gsappend :: (:+:) l r x -> (:+:) l r x -> (:+:) l r x
gsappend = [Char] -> (:+:) l r x -> (:+:) l r x -> (:+:) l r x
forall a. HasCallStack => [Char] -> a
error [Char]
"GSemigroup :+:"