{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE IncoherentInstances #-} module Control.Interchangeable ( Interchangeable (..) ) where import qualified Data.Set import qualified Data.Map -- | -- Minimal definition is ('interchange', 'interchange'') and ('applyI', -- 'applyI'') or ('modifyI', 'modifyI''). class Interchangeable a b where -- | Interchange a with b interchange :: a -> b -- | Interchange b with a interchange' :: b -> a -- | Append a to b applyI :: a -> b -> b applyI a b = modifyI' b (const a) -- | Append b to a applyI' :: b -> a -> a applyI' b a = modifyI a (const b) -- | Modify a with an operation to b modifyI :: a -> (b -> b) -> a modifyI a f = applyI' (f (interchange a)) a -- | Modify a with an operation to b modifyI' :: b -> (a -> a) -> b modifyI' b f = applyI (f (interchange' b)) b instance (Interchangeable a b) => Interchangeable b a where interchange = interchange' interchange' = interchange applyI = applyI' applyI' = applyI instance (Ord a) => Interchangeable [a] (Data.Set.Set a) where interchange = Data.Set.fromList interchange' = Data.Set.toList applyI a = Data.Set.union (Data.Set.fromList a) applyI' b a = a ++ Data.Set.toList b instance (Ord k) => Interchangeable [(k,a)] (Data.Map.Map k a) where interchange = Data.Map.fromList interchange' = Data.Map.toList applyI a = Data.Map.union (Data.Map.fromList a) applyI' b a = a ++ Data.Map.toList b