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

module Data.TrieMap.Class (TMap(..), TKey(..), Rep, Ordered (..), TrieMap, TrieKey) where

import Data.TrieMap.TrieKey
import Data.TrieMap.OrdMap

import Control.Applicative
import Data.Foldable
import Data.Traversable

-- import Generics.MultiRec.Base
import Data.TrieMap.Regular.Base
import Data.TrieMap.Regular.Sized

import Prelude hiding (foldr)

newtype TMap k a = TMap {getTMap :: TrieMap (Rep k) (K0 a) (Rep k)}

type family Rep k

class TrieKey (Rep k) (TrieMap (Rep k)) => TKey k where
	toRep :: k -> Rep k
	fromRep :: Rep k -> k

instance TKey k => Functor (TMap k) where
	fmap = fmapDefault

instance TKey k => Foldable (TMap k) where
	foldr f z (TMap m) = foldWithKeyM (\ _ (K0 a) -> f a) m z

instance TKey k => Traversable (TMap k) where
	traverse = trv
-- 	traverse f (TMap m) = TMap <$> traverseWithKeyM (\ _ (K0 a) -> K0 <$> f a) m
trv :: (Applicative f, TKey k) => (a -> f b) -> TMap k a -> f (TMap k b)
trv f (TMap m) = TMap <$> traverseWithKeyM sizeK0 (\ _ (K0 a) -> K0 <$> f a) m