packages feed

HaRe-0.6: tools/TFF/TFFMonad.hs

module TFFMonad where

import Syntax 
import TypesTerms
import Char(chr,ord)

--------------------------------------------------------------------------------
-- The monad
--

type Env        = [(HsName, Term)]
type FreshVars  = (Int, Int, Int)   

tvarCtr (x,_,_) = x
funCtr  (_,x,_) = x
valCtr  (_,_,x) = x

incTvarCtr (x,y,z)  = (x+1, y, z)
incFunCtr  (x,y,z)  = (x, y+1, z)
incValCtr  (x,y,z)  = (x, y, z+1)

valName fvs     = UnQual $ 'x' : show (valCtr fvs)
funName fvs     = UnQual $ [chr (funCtr fvs + ord 'f')]
tvarName fvs    = UnQual $ [chr (tvarCtr fvs + ord 'A')]


newtype FM a    = FM ( (FreshVars, Env) -> (a, FreshVars) )

instance Monad FM where
    return x        = FM (\(fvs, e) -> (x, fvs))
    FM f >>= g      = FM bind
        where
        bind (fvs, e) =  
            let (a, fvs')   = f (fvs, e)
                FM h        = g a
            in h (fvs', e)

inExtendedEnv :: HsName -> Term -> FM a -> FM a
inExtendedEnv n t (FM f) = FM (\(fvs, e) -> f (fvs, (n, t):e))

lookUp :: HsName -> FM Term
lookUp n = FM (\(fvs, e) -> (maybe no id (lookup n e), fvs))
    where
    no = error $ "lookUp: " ++ (show n) ++ " not in environment."


newVar :: Type -> FM Term
newVar t = FM f
    where
    f (fvs, e) = if isFun t
        then ( (hsEVar (funName fvs) ,t) , incFunCtr fvs ) 
        else ( (hsEVar (valName fvs) ,t) , incValCtr fvs ) 

newTVar :: FM Type
newTVar = FM f
    where
    f (fvs, e)  = (mkTyVar (tvarName fvs), incTvarCtr fvs)


run :: FM a -> a
run (FM f) = let (v, _) = f ((0,0,0), []) in v


--
--------------------------------------------------------------------------------