{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE TypeFamilies #-} #if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE DeriveGeneric #-} #endif #if __GLASGOW_HASKELL__ >= 706 {-# LANGUAGE PolyKinds #-} #endif #if __GLASGOW_HASKELL__ >= 708 {-# LANGUAGE Safe #-} #elif __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif module Data.Bifunctor.Sum where import Data.Bifunctor import Data.Bifunctor.Functor import Data.Bifoldable import Data.Bitraversable #if __GLASGOW_HASKELL__ < 710 import Data.Functor #endif #if __GLASGOW_HASKELL__ >= 708 import Data.Typeable #endif #if __GLASGOW_HASKELL__ >= 702 import GHC.Generics #endif data Sum p q a b = L2 (p a b) | R2 (q a b) deriving ( Eq, Ord, Show, Read #if __GLASGOW_HASKELL__ >= 702 , Generic #endif #if __GLASGOW_HASKELL__ >= 708 , Generic1 , Typeable #endif ) #if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 708 data SumMetaData data SumMetaConsL2 data SumMetaConsR2 instance Datatype SumMetaData where datatypeName _ = "Sum" moduleName _ = "Data.Bifunctor.Sum" instance Constructor SumMetaConsL2 where conName _ = "L2" instance Constructor SumMetaConsR2 where conName _ = "R2" instance Generic1 (Sum p q a) where type Rep1 (Sum p q a) = D1 SumMetaData ((:+:) (C1 SumMetaConsL2 (S1 NoSelector (Rec1 (p a)))) (C1 SumMetaConsR2 (S1 NoSelector (Rec1 (q a))))) from1 (L2 p) = M1 (L1 (M1 (M1 (Rec1 p)))) from1 (R2 q) = M1 (R1 (M1 (M1 (Rec1 q)))) to1 (M1 (L1 (M1 (M1 p)))) = L2 (unRec1 p) to1 (M1 (R1 (M1 (M1 q)))) = R2 (unRec1 q) #endif instance (Bifunctor p, Bifunctor q) => Bifunctor (Sum p q) where bimap f g (L2 p) = L2 (bimap f g p) bimap f g (R2 q) = R2 (bimap f g q) first f (L2 p) = L2 (first f p) first f (R2 q) = R2 (first f q) second f (L2 p) = L2 (second f p) second f (R2 q) = R2 (second f q) instance (Bifoldable p, Bifoldable q) => Bifoldable (Sum p q) where bifoldMap f g (L2 p) = bifoldMap f g p bifoldMap f g (R2 q) = bifoldMap f g q instance (Bitraversable p, Bitraversable q) => Bitraversable (Sum p q) where bitraverse f g (L2 p) = L2 <$> bitraverse f g p bitraverse f g (R2 q) = R2 <$> bitraverse f g q instance BifunctorFunctor (Sum p) where bifmap _ (L2 p) = L2 p bifmap f (R2 q) = R2 (f q) instance BifunctorMonad (Sum p) where bireturn = R2 bijoin (L2 p) = L2 p bijoin (R2 q) = q bibind _ (L2 p) = L2 p bibind f (R2 q) = f q