sourcecode:
|
module FlatCurry.Normalize ( normalizeTypeExpr )
where
import Control.Monad.Trans.State
import FlatCurry.Types
------------------------------------------------------------------------------
-- The state used during the normalization process.
-- The state consists of a current number for enumerating type variables
-- and a mapping from the original type variable indices into
-- normalized indices (which will be expanded during the transformation).
data TransInfo = TransInfo { currNr :: TVarIndex
, tvarMap :: [(TVarIndex,TVarIndex)]
}
-- The initial state.
initState :: TransInfo
initState = TransInfo 0 []
-- The type of the state normalization monad.
type TransState a = State TransInfo a
-- Auxiliary operation: get a unique index for a given type variable.
-- Either return the existing index or create a fresh one and update
-- the state.
getTVarIndex :: TVarIndex -> TransState TVarIndex
getTVarIndex v = do
ti <- get
maybe (do let nv = currNr ti
put ti { currNr = nv + 1, tvarMap = (v,nv) : tvarMap ti }
return nv )
return
(lookup v (tvarMap ti))
------------------------------------------------------------------------------
--- Normalize a type expression by enumerating the type variables
--- starting from `0`.
normalizeTypeExpr :: TypeExpr -> TypeExpr
normalizeTypeExpr texp = evalState (normTExp texp) initState
-- The actual implementation of the normalization task performs
-- a monadic traversal over the given type expression.
normTExp :: TypeExpr -> TransState TypeExpr
normTExp texp = case texp of
TVar v -> do vi <- getTVarIndex v
return $ TVar vi
FuncType t1 t2 -> do
nt1 <- normTExp t1
nt2 <- normTExp t2
return (FuncType nt1 nt2)
TCons qn tes -> do
ntes <- mapM normTExp tes
return $ TCons qn ntes
ForallType tvs te -> do
ntvs <- mapM normTVarWithKind tvs
nte <- normTExp te
return $ ForallType ntvs nte
where
normTVarWithKind (v,k) = do
vi <- getTVarIndex v
return (vi,k)
-----------------------------------------------------------------------
|