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

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

import Data.TrieMap.TrieKey
import Data.TrieMap.OrdMap
import Data.TrieMap.Rep
import Data.TrieMap.Sized

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

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

import Prelude hiding (foldr)

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

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

instance (Repr k, TrieKey (Rep k) (TrieMap (Rep k))) => TKey k

class (ReprT f, TrieKeyT (RepT f) (TrieMapT (RepT f))) => TKeyT f

instance (ReprT f, TrieKeyT (RepT f) (TrieMapT (RepT f))) => TKeyT f

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

instance TKey k => Foldable (TMap k) where
	foldr f z (TMap m) = foldWithKeyM (\ _ (Elem 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 elemSize (\ _ (Elem a) -> Elem <$> f a) m