{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Agda.Utils.BiMap where
import Prelude hiding (lookup, unzip)
import Control.Applicative ((<*>))
import Data.Function
import Data.Functor
import qualified Data.List as List
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Tuple
data BiMap a b = BiMap
{ biMapThere :: Map a b
, biMapBack :: Map b a
}
lookup :: Ord a => a -> BiMap a b -> Maybe b
lookup a = Map.lookup a . biMapThere
invLookup :: Ord b => b -> BiMap a b -> Maybe a
invLookup b = Map.lookup b . biMapBack
empty :: BiMap a b
empty = BiMap Map.empty Map.empty
singleton :: a -> b -> BiMap a b
singleton a b = BiMap (Map.singleton a b) (Map.singleton b a)
insert :: (Ord a, Ord b) => a -> b -> BiMap a b -> BiMap a b
insert a b (BiMap t u) = BiMap (Map.insert a b t) (Map.insert b a u)
union :: (Ord a, Ord b) => BiMap a b -> BiMap a b -> BiMap a b
union (BiMap t1 b1) (BiMap t2 b2) = BiMap (Map.union t1 t2) (Map.union b1 b2)
fromList :: (Ord a, Ord b) => [(a,b)] -> BiMap a b
fromList = List.foldl' (flip (uncurry insert)) empty
toList :: BiMap a b -> [(a,b)]
toList = Map.toAscList . biMapThere
instance (Ord a, Ord b) => Eq (BiMap a b) where
(==) = (==) `on` biMapThere
instance (Ord a, Ord b) => Ord (BiMap a b) where
compare = compare `on` biMapThere
instance (Show a, Show b) => Show (BiMap a b) where
show bimap = "Agda.Utils.BiMap.fromList " ++ show (toList bimap)