module NetSpider.Pair
( Pair(..),
sortPair
) where
import Control.Applicative (Applicative(..))
import Data.Foldable (Foldable(..))
import Data.Hashable (Hashable(hashWithSalt))
import Data.Traversable (Traversable(..))
newtype Pair a = Pair { unPair :: (a,a) }
deriving (Show)
instance Eq a => Eq (Pair a) where
(Pair (al, ar)) == (Pair (bl, br)) = (al == bl && ar == br) || (al == br && ar == bl)
instance Ord a => Ord (Pair a) where
compare l r = compare (unPair $ sortPair l) (unPair $ sortPair r)
instance (Ord a, Hashable a) => Hashable (Pair a) where
hashWithSalt s p = hashWithSalt s $ unPair $ sortPair p
instance Functor Pair where
fmap f (Pair (l,r)) = Pair (f l, f r)
instance Applicative Pair where
pure a = Pair (a,a)
(Pair (fl,fr)) <*> (Pair (al,ar)) = Pair (fl al, fr ar)
instance Foldable Pair where
foldr f start (Pair (l,r)) = foldr f start [l,r]
instance Traversable Pair where
traverse f (Pair (l,r)) = fmap Pair $ (,) <$> (f l) <*> (f r)
sortPair :: Ord a => Pair a -> Pair a
sortPair p@(Pair (l,r)) = if l <= r
then p
else Pair (r,l)