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

module TrieMap.Reflection where

-- import TrieMap.Fixpoint
import TrieMap.TrieAlgebraic
import TrieMap.Algebraic
import TrieMap.Applicative
import TrieMap.RadixTrie()
import qualified TrieMap.TrieAlgebraic as TA

instance Algebraic (m1 (m2 v)) => Algebraic (ProdMap m1 m2 v) where
	type Alg (ProdMap m1 m2 v) = Alg (m1 (m2 v))
	toAlg (PMap m) = toAlg m
	fromAlg = PMap . fromAlg

instance (Algebraic (m1 v), Algebraic (m2 v)) => Algebraic (UnionMap m1 m2 v) where
	type Alg (UnionMap m1 m2 v) = (Alg (m1 v), Alg (m2 v))
	toAlg (m1 :+: m2) = (toAlg m1, toAlg m2)
	fromAlg (m1, m2) = fromAlg m1 :+: fromAlg m2

instance (Ord k, Algebraic k, Algebraic v, TrieKey k m) => Algebraic (RadixTrie k m v) where
	type Alg (RadixTrie k m v) = Alg [([k], v)]
	toAlg m = toAlg (build (\ c n -> foldWithKeyAlg (curry c) n m))
	fromAlg = fromDistAscListAlg . fromAlg