{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE IncoherentInstances #-} module Control.Interchangeable ( Interchangeable (..) ) where import qualified Data.Set import qualified Data.Map class Interchangeable a b where -- | Interchange a with b aToB :: a -> b -- | Interchange b with a bToA :: b -> a -- | Append a to b appendAToB :: a -> b -> b appendAToB a b = modifyBWithA b (const a) -- | Append b to a appendBToA :: b -> a -> a appendBToA b a = modifyAWithB a (const b) -- | Modify a with an operation to b modifyAWithB :: a -> (b -> b) -> a modifyAWithB a f = appendBToA (f (aToB a)) a -- | Modify a with an operation to b modifyBWithA :: b -> (a -> a) -> b modifyBWithA b f = appendAToB (f (bToA b)) b instance (Interchangeable a b) => Interchangeable b a where aToB = bToA bToA = aToB appendAToB = appendBToA appendBToA = appendAToB instance (Ord a) => Interchangeable [a] (Data.Set.Set a) where aToB = Data.Set.fromList bToA = Data.Set.toList appendAToB a = Data.Set.union (Data.Set.fromList a) appendBToA b a = a ++ Data.Set.toList b instance (Ord k) => Interchangeable [(k,a)] (Data.Map.Map k a) where aToB = Data.Map.fromList bToA = Data.Map.toList appendAToB a = Data.Map.union (Data.Map.fromList a) appendBToA b a = a ++ Data.Map.toList b