{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | The Symbols monad provides two separate sources of atoms, for
-- converting objects to unique atoms (represented as Ints)
module NLP.Symbols 
       ( Symbols
       , module Control.Monad.Atom
       , toAtomA
       , toAtomB
       , fromAtomA
       , fromAtomB
       , evalSymbols
       , runSymbols
       )
where       
import Control.Monad.Atom  
import Control.Monad.Trans

newtype Symbols a b r = Symbols  (AtomT a (Atom b) r)
                      deriving (Functor, Monad)

toAtomA :: (Ord a) => a -> Symbols a b Int
toAtomA = Symbols . toAtom

toAtomB :: (Ord b) => b -> Symbols a b Int
toAtomB = Symbols . lift . toAtom

fromAtomA :: (Ord a) => Int -> Symbols a b a
fromAtomA = Symbols . fromAtom

fromAtomB :: (Ord b) => Int -> Symbols a b b
fromAtomB = Symbols . lift . fromAtom

evalSymbols :: (Ord a, Ord b) => Symbols a b r -> r
evalSymbols (Symbols s) = evalAtom $ evalAtomT s

runSymbols :: (Ord a, Ord b) =>
     Symbols a b t
     -> AtomTable a -> AtomTable b -> (t, AtomTable a, AtomTable b)
runSymbols (Symbols s) y z = 
  let ((r,a),b) = runAtom (runAtomT s y) z                             
  in (r,a,b)