{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.Tuple where

import Control.Monad
import Data.Monoid

instance (Magma a, Magma b) => Magma (a, b) where
    (a, b) `op` (c, d) = (a `op` c, b `op` d)

instance (Semigroup a, Semigroup b) => Semigroup (a, b)

instance (Unital a, Unital b) => Unital (a, b) where
    unit = (unit, unit)

instance (Monoid a, Monoid b) => Monoid (a, b)

instance Functor Hask ((,) a) where
    f $> (a, b) = (a, f b)

instance Unital u => Pointed Hask ((,) u) where
    point x = (unit, x)

instance Monoid o => Applicative Hask ((,) o) where
    (a, f) <$> (b, x) = (a `op` b, f x)

instance Monoid o => Monad Hask ((,) o) where
    join (a, (b, x)) = (a `op` b, x)

instance Copointed Hask ((,) a) where
    extract (_, x) = x

instance Comonad Hask ((,) a) where
    cojoin (x, y) = (x, (x, y))
