{-# LANGUAGE TupleSections #-} -- | Extra functions for working with pairs and triples. -- Some of these functions are available in the "Control.Arrow" module, -- but here are available specialised to pairs. Some operations work on triples. module Data.Tuple.Extra( module Data.Tuple, -- * Specialised 'Arrow' functions first, second, (***), (&&&), -- * More pair operations dupe, both, -- * Monadic versions firstM, secondM, -- * Operations on triple fst3, snd3, thd3, first3, second3, third3, curry3, uncurry3 ) where import Data.Tuple import qualified Control.Arrow as Arrow infixr 3 ***, &&& -- | Update the first component of a pair. -- -- > first succ (1,"test") == (2,"test") first :: (a -> a') -> (a, b) -> (a', b) first = Arrow.first -- | Update the second component of a pair. -- -- > second reverse (1,"test") == (1,"tset") second :: (b -> b') -> (a, b) -> (a, b') second = Arrow.second -- | Update the first component of a pair. -- -- > firstM (\x -> [x-1, x+1]) (1,"test") == [(0,"test"),(2,"test")] firstM :: Functor m => (a -> m a') -> (a, b) -> m (a', b) firstM f (a,b) = (,b) <\$> f a -- | Update the second component of a pair. -- -- > secondM (\x -> [reverse x, x]) (1,"test") == [(1,"tset"),(1,"test")] secondM :: Functor m => (b -> m b') -> (a, b) -> m (a, b') secondM f (a,b) = (a,) <\$> f b -- | Given two functions, apply one to the first component and one to the second. -- A specialised version of 'Control.Arrow.***'. -- -- > (succ *** reverse) (1,"test") == (2,"tset") (***) :: (a -> a') -> (b -> b') -> (a, b) -> (a', b') (***) = (Arrow.***) -- | Given two functions, apply both to a single argument to form a pair. -- A specialised version of 'Control.Arrow.&&&'. -- -- > (succ &&& pred) 1 == (2,0) (&&&) :: (a -> b) -> (a -> c) -> a -> (b, c) (&&&) = (Arrow.&&&) -- | Duplicate a single value into a pair. -- -- > dupe 12 == (12, 12) dupe :: a -> (a,a) dupe x = (x,x) -- | Apply a single function to both components of a pair. -- -- > both succ (1,2) == (2,3) both :: (a -> b) -> (a, a) -> (b, b) both f (x,y) = (f x, f y) -- | Extract the 'fst' of a triple. fst3 :: (a,b,c) -> a fst3 (a,b,c) = a -- | Extract the 'snd' of a triple. snd3 :: (a,b,c) -> b snd3 (a,b,c) = b -- | Extract the final element of a triple. thd3 :: (a,b,c) -> c thd3 (a,b,c) = c -- | Converts an uncurried function to a curried function. curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d curry3 f a b c = f (a,b,c) -- | Converts a curried function to a function on a triple. uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d) uncurry3 f ~(a,b,c) = f a b c -- | Update the first component of a triple. -- -- > first3 succ (1,1,1) == (2,1,1) 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 succ (1,1,1) == (1,2,1) 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 succ (1,1,1) == (1,1,2) third3 :: (c -> c') -> (a, b, c) -> (a, b, c') third3 f (a,b,c) = (a,b,f c)