bifunctors-5.5.5: src/Data/Bifunctor/Sum.hs
{-# 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
#include "bifunctors-common.h"
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
import Data.Monoid hiding (Sum)
#endif
#if __GLASGOW_HASKELL__ >= 708
import Data.Typeable
#endif
#if __GLASGOW_HASKELL__ >= 702
import GHC.Generics
#endif
#if LIFTED_FUNCTOR_CLASSES
import Data.Functor.Classes
#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
#if LIFTED_FUNCTOR_CLASSES
instance (Eq2 f, Eq2 g, Eq a) => Eq1 (Sum f g a) where
liftEq = liftEq2 (==)
instance (Eq2 f, Eq2 g) => Eq2 (Sum f g) where
liftEq2 f g (L2 x1) (L2 x2) = liftEq2 f g x1 x2
liftEq2 _ _ (L2 _) (R2 _) = False
liftEq2 _ _ (R2 _) (L2 _) = False
liftEq2 f g (R2 y1) (R2 y2) = liftEq2 f g y1 y2
instance (Ord2 f, Ord2 g, Ord a) => Ord1 (Sum f g a) where
liftCompare = liftCompare2 compare
instance (Ord2 f, Ord2 g) => Ord2 (Sum f g) where
liftCompare2 f g (L2 x1) (L2 x2) = liftCompare2 f g x1 x2
liftCompare2 _ _ (L2 _) (R2 _) = LT
liftCompare2 _ _ (R2 _) (L2 _) = GT
liftCompare2 f g (R2 y1) (R2 y2) = liftCompare2 f g y1 y2
instance (Read2 f, Read2 g, Read a) => Read1 (Sum f g a) where
liftReadsPrec = liftReadsPrec2 readsPrec readList
instance (Read2 f, Read2 g) => Read2 (Sum f g) where
liftReadsPrec2 rp1 rl1 rp2 rl2 = readsData $
readsUnaryWith (liftReadsPrec2 rp1 rl1 rp2 rl2) "L2" L2 `mappend`
readsUnaryWith (liftReadsPrec2 rp1 rl1 rp2 rl2) "R2" R2
instance (Show2 f, Show2 g, Show a) => Show1 (Sum f g a) where
liftShowsPrec = liftShowsPrec2 showsPrec showList
instance (Show2 f, Show2 g) => Show2 (Sum f g) where
liftShowsPrec2 sp1 sl1 sp2 sl2 p (L2 x) =
showsUnaryWith (liftShowsPrec2 sp1 sl1 sp2 sl2) "L2" p x
liftShowsPrec2 sp1 sl1 sp2 sl2 p (R2 y) =
showsUnaryWith (liftShowsPrec2 sp1 sl1 sp2 sl2) "R2" p y
#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