-- | Extra functions for working with tuples.
-- Some of these functions are available in the "Control.Arrow" module,
-- but here are available specialised to pairs.
module Data.Tuple.Extra(
module Data.Tuple,
-- * Specialised 'Arrow' functions
first, second, (***), (&&&),
-- * More pair operations
dupe, both,
-- * Operations on triples
fst3, snd3, thd3, first3, second3, third3, dupe3, both3,
) where
import Data.Tuple
import qualified Control.Arrow as Arrow
infixr 3 ***, &&&
-- | Update the first component of a pair.
first :: (a -> a') -> (a, b) -> (a', b)
first = Arrow.first
-- | Update the second component of a pair.
second :: (b -> b') -> (a, b) -> (a, b')
second = Arrow.second
(***) :: (a -> a') -> (b -> b') -> (a, b) -> (a', b')
(***) = (Arrow.***)
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
(&&&) = (Arrow.&&&)
dupe :: a -> (a,a)
dupe x = (x,x)
both :: (a -> b) -> (a, a) -> (b, b)
both f (x,y) = (f x, f y)
fst3 :: (a,b,c) -> a
fst3 (a,b,c) = a
snd3 :: (a,b,c) -> b
snd3 (a,b,c) = b
thd3 :: (a,b,c) -> c
thd3 (a,b,c) = c
-- | Update the first component of a triple.
first3 :: (a -> a') -> (a, b, c) -> (a', b, c)
first3 f (a,b,c) = (f a, b, c)
-- | Update the second component of a triple.
second3 :: (b -> b') -> (a, b, c) -> (a, b', c)
second3 f (a,b,c) = (a, f b, c)
-- | Update the third component of a triple.
third3 :: (c -> c') -> (a, b, c) -> (a, b, c')
third3 f (a,b,c) = (a, b, f c)
dupe3 :: a -> (a,a,a)
dupe3 x = (x,x,x)
both3 :: (a -> b) -> (a, a, a) -> (b, b, b)
both3 f (x,y,z) = (f x, f y, f z)