--- /dev/null
+\r
+A simple homogeneous pair type with useful Functor, Applicative, and\r
+Traversable instances.\r
+\r
+\begin{code}\r
+module Pair ( Pair(..), unPair, toPair, swap ) where\r
+\r
+#include "HsVersions.h"\r
+\r
+import Outputable\r
+import Data.Monoid\r
+import Control.Applicative\r
+import Data.Foldable\r
+import Data.Traversable\r
+\r
+data Pair a = Pair { pFst :: a, pSnd :: a }\r
+-- Note that Pair is a *unary* type constructor\r
+-- whereas (,) is binary\r
+\r
+-- The important thing about Pair is that it has a *homogenous*\r
+-- Functor instance, so you can easily apply the same function\r
+-- to both components\r
+instance Functor Pair where\r
+ fmap f (Pair x y) = Pair (f x) (f y)\r
+\r
+instance Applicative Pair where\r
+ pure x = Pair x x\r
+ (Pair f g) <*> (Pair x y) = Pair (f x) (g y)\r
+\r
+instance Foldable Pair where\r
+ foldMap f (Pair x y) = f x `mappend` f y\r
+\r
+instance Traversable Pair where\r
+ traverse f (Pair x y) = Pair <$> f x <*> f y\r
+\r
+instance Outputable a => Outputable (Pair a) where\r
+ ppr (Pair a b) = ppr a <+> char '~' <+> ppr b\r
+\r
+unPair :: Pair a -> (a,a)\r
+unPair (Pair x y) = (x,y)\r
+\r
+toPair :: (a,a) -> Pair a\r
+toPair (x,y) = Pair x y\r
+\r
+swap :: Pair a -> Pair a\r
+swap (Pair x y) = Pair y x\r
+\end{code}
\ No newline at end of file