{-# LANGUAGE TypeFamilies #-}
module Data.TrieMap.Representation.Class where

import Data.Vector

-- | The @Repr@ type class denotes that a type can be decomposed to a representation
-- built out of pieces for which the 'TrieKey' class defines a generalized trie structure.
-- 
-- It is required that, if @('Repr' a, 'Eq' a)@, and @x, y :: a@, then @x '==' y@
-- if and only if @'toRep' x '==' 'toRep' y@.  It is typically the case that
-- @'compare' x y == 'compare' ('toRep' x) ('toRep' y)@, as well, but this is not
-- strictly required.  (It is, however, the case for all instances built into the package.)
-- 
-- As an additional note, the 'Key' modifier is used for \"bootstrapping\" 'Repr' instances,
-- allowing a type to be used in its own 'Repr' definition when wrapped in a 'Key' modifier.
class Repr a where
  type Rep a
  type RepList a
  toRep :: a -> Rep a
  toRepList :: [a] -> RepList a

type DRepList a = Vector (Rep a)
dToRepList :: Repr a => [a] -> DRepList a
dToRepList = fromList . Prelude.map toRep

instance Repr a => Repr [a] where
  type Rep [a] = RepList a
  type RepList [a] = Vector (RepList a)
  toRep = toRepList
  toRepList = dToRepList