{-# LANGUAGE UndecidableInstances, FlexibleContexts, TypeFamilies, KindSignatures #-}

module Data.TrieMap.Rep where

class Repr a where
	type Rep a
	toRep :: a -> Rep a
	fromRep :: Rep a -> a

class Functor (RepT f) => ReprT f where
	type RepT f :: * -> *
	toRepT :: f a -> RepT f a
	fromRepT :: RepT f a -> f a
	toRepTMap :: (a -> b) -> f a -> RepT f b
	fromRepTMap :: (b -> a) -> RepT f b -> f a

	toRepT = toRepTMap id
	fromRepT = fromRepTMap id
	toRepTMap f = fmap f . toRepT
	fromRepTMap f = fromRepT . fmap f

{-# RULES
	"toRep/fromRep" forall x . toRep (fromRep x) = x;
-- 	"fromRep/toRep" forall x . fromRep (toRep x) = x;
	#-}