module Data.Bijection.Class where
import Control.Applicative ((<$>))
import Control.DeepSeq
import Data.Aeson
import Data.Binary
import Data.Serialize
import Data.Tuple (swap)
import GHC.Generics
import Prelude (Bool,Maybe,map,($),Int, maybe, id, (.), seq, Read, Show, Eq, return)
import Data.List (foldl')
data Bimap l r = Bimap !l !r
deriving (Read,Show,Eq,Generic)
class DomCod z where
type Dom z :: *
type Cod z :: *
member :: z -> Dom z -> Bool
lookup :: z -> Dom z -> Maybe (Cod z)
deleteDC :: z -> Dom z -> Maybe (Cod z, z)
insertDC :: z -> (Dom z,Cod z) -> z
toListDC :: z -> [(Dom z, Cod z)]
nullDC :: z -> Bool
emptyDC :: z
sizeDC :: z -> Int
fromListDC :: [(Dom z, Cod z)] -> z
instance (NFData l, NFData r) => NFData (Bimap l r) where
rnf (Bimap l r) = rnf l `seq` rnf r `seq` ()
instance (Binary l, Binary r) => Binary (Bimap l r)
instance (Serialize l, Serialize r) => Serialize (Bimap l r)
instance (DomCodCnt l r, ToJSON (Dom l), ToJSON (Dom r)) => ToJSON (Bimap l r) where
toJSON = toJSON . toList
instance (DomCodCnt l r, FromJSON (Dom l), FromJSON (Dom r)) => FromJSON (Bimap l r) where
parseJSON j = fromList <$> parseJSON j
type DomCodCnt l r = (DomCod l, DomCod r, Dom l ~ Cod r, Dom r ~ Cod l)
contL :: Bimap l r -> l
contL (Bimap l r) = l
contR :: Bimap l r -> r
contR (Bimap l r) = r
memberL :: (DomCod l) => Bimap l r -> Dom l -> Bool
memberL (Bimap l r) e = member l e
memberR :: (DomCod r) => Bimap l r -> Dom r -> Bool
memberR (Bimap l r) e = member r e
lookupL :: (DomCod l) => Bimap l r -> Dom l -> Maybe (Cod l)
lookupL (Bimap l r) k = lookup l k
lookupR :: (DomCod r) => Bimap l r -> Dom r -> Maybe (Cod r)
lookupR (Bimap l r) k = lookup r k
empty :: (DomCodCnt l r) => Bimap l r
empty = Bimap emptyDC emptyDC
null :: DomCod l => Bimap l r -> Bool
null (Bimap l r) = nullDC l
size :: DomCod l => Bimap l r -> Int
size (Bimap l r) = sizeDC l
fromList :: DomCodCnt l r => [(Dom l, Dom r)] -> Bimap l r
fromList = foldl' insert empty
toList :: DomCodCnt l r => Bimap l r -> [(Dom l, Dom r)]
toList (Bimap l r) = toListDC l
insert :: (DomCodCnt l r) => Bimap l r -> (Dom l, Cod l) -> Bimap l r
insert (Bimap l r) (u,v) = Bimap (insertDC l (u,v)) (insertDC r (v,u))
deleteByL :: DomCodCnt l r => Bimap l r -> Dom l -> Bimap l r
deleteByL b@(Bimap l r) k = maybe b id $ do
(k',l') <- deleteDC l k
(_ ,r') <- deleteDC r k'
return $ Bimap l' r'
deleteByR :: DomCodCnt l r => Bimap l r -> Dom r -> Bimap l r
deleteByR b@(Bimap l r) k = maybe b id $ do
(k',r') <- deleteDC r k
(_ ,l') <- deleteDC l k'
return $ Bimap l' r'
findWithDefaultL :: DomCodCnt l r => Cod l -> Bimap l r -> Dom l -> Cod l
findWithDefaultL def = (maybe def id . ) . lookupL
findWithDefaultR :: DomCodCnt l r => Cod r -> Bimap l r -> Dom r -> Cod r
findWithDefaultR def = (maybe def id . ) . lookupR