    {-
    A simple homogeneous pair type with useful Functor, Applicative, and
    Traversable instances.
    -}

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE DeriveFunctor #-}

    module GHC.Data.Pair
       ( Pair(..)
       , unPair
       , toPair
       , swap
       , pLiftFst
       , pLiftSnd
       )
    where

    #include "HsVersions.h"

    import GHC.Prelude

    import GHC.Utils.Outputable
    import qualified Data.Semigroup as Semi

    data Pair a = Pair { forall a. Pair a -> a
    pFst :: a, forall a. Pair a -> a
    pSnd :: a }
      deriving (forall a b. a -> Pair b -> Pair a
    forall a b. (a -> b) -> Pair a -> Pair b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    <$ :: forall a b. a -> Pair b -> Pair a
    $c<$ :: forall a b. a -> Pair b -> Pair a
    fmap :: forall a b. (a -> b) -> Pair a -> Pair b
    $cfmap :: forall a b. (a -> b) -> Pair a -> Pair b
    Functor)
    -- Note that Pair is a *unary* type constructor
    -- whereas (,) is binary

    -- The important thing about Pair is that it has a *homogeneous*
    -- Functor instance, so you can easily apply the same function
    -- to both components

    instance Applicative Pair where
      pure :: forall a. a -> Pair a
    pure a
    x = forall a. a -> a -> Pair a
    Pair a
    x a
    x
      (Pair a -> b
    f a -> b
    g) <*> :: forall a b. Pair (a -> b) -> Pair a -> Pair b
    <*> (Pair a
    x a
    y) = forall a. a -> a -> Pair a
    Pair (a -> b
    f a
    x) (a -> b
    g a
    y)

    instance Foldable Pair where
      foldMap :: forall m a. Monoid m => (a -> m) -> Pair a -> m
    foldMap a -> m
    f (Pair a
    x a
    y) = a -> m
    f a
    x forall a. Monoid a => a -> a -> a
    `mappend` a -> m
    f a
    y

    instance Traversable Pair where
      traverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Pair a -> f (Pair b)
    traverse a -> f b
    f (Pair a
    x a
    y) = forall a. a -> a -> Pair a
    Pair forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> a -> f b
    f a
    x forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> a -> f b
    f a
    y

    instance Semi.Semigroup a => Semi.Semigroup (Pair a) where
      Pair a
    a1 a
    b1 <> :: Pair a -> Pair a -> Pair a
    <> Pair a
    a2 a
    b2 =  forall a. a -> a -> Pair a
    Pair (a
    a1 forall a. Semigroup a => a -> a -> a
    Semi.<> a
    a2) (a
    b1 forall a. Semigroup a => a -> a -> a
    Semi.<> a
    b2)

    instance (Semi.Semigroup a, Monoid a) => Monoid (Pair a) where
      mempty :: Pair a
    mempty = forall a. a -> a -> Pair a
    Pair forall a. Monoid a => a
    mempty forall a. Monoid a => a
    mempty
      mappend :: Pair a -> Pair a -> Pair a
    mappend = forall a. Semigroup a => a -> a -> a
    (Semi.<>)

    instance Outputable a => Outputable (Pair a) where
      ppr :: Pair a -> SDoc
    ppr (Pair a
    a a
    b) = forall a. Outputable a => a -> SDoc
    ppr a
    a SDoc -> SDoc -> SDoc
    <+> Char -> SDoc
    char Char
    '~' SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr a
    b

    unPair :: Pair a -> (a,a)
    unPair :: forall a. Pair a -> (a, a)
    unPair (Pair a
    x a
    y) = (a
    x,a
    y)

    toPair :: (a,a) -> Pair a
    toPair :: forall a. (a, a) -> Pair a
    toPair (a
    x,a
    y) = forall a. a -> a -> Pair a
    Pair a
    x a
    y

    swap :: Pair a -> Pair a
    swap :: forall a. Pair a -> Pair a
    swap (Pair a
    x a
    y) = forall a. a -> a -> Pair a
    Pair a
    y a
    x

    pLiftFst :: (a -> a) -> Pair a -> Pair a
    pLiftFst :: forall a. (a -> a) -> Pair a -> Pair a
    pLiftFst a -> a
    f (Pair a
    a a
    b) = forall a. a -> a -> Pair a
    Pair (a -> a
    f a
    a) a
    b

    pLiftSnd :: (a -> a) -> Pair a -> Pair a
    pLiftSnd :: forall a. (a -> a) -> Pair a -> Pair a
    pLiftSnd a -> a
    f (Pair a
    a a
    b) = forall a. a -> a -> Pair a
    Pair a
    a (a -> a
    f a
    b)