Fixed HLint warnings in Rename.

- Added type signatures.
- Cleaned us renaming.
- Added wrapper around state monad.
- Renamed pattern_extend and pattern_rename to patternExtend and patternRename
  to conform with convention.
This commit is contained in:
Abhinav Gupta 2012-04-27 01:29:13 -07:00
parent 84a90b44d5
commit a666e9bf86

View file

@ -1,73 +1,97 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Rename (rename) where module Rename (rename) where
import Ast import Ast
import Control.Arrow (first) import Control.Arrow (first)
import Control.Monad.State import Control.Monad (ap, liftM, foldM, mapM, Monad)
import Control.Monad.State (evalState, State, get, put)
import Data.Char (isLower) import Data.Char (isLower)
import Data.List (mapAccumL)
import Data.Functor.Identity
rename expr = evalState (rename' id expr) 0 -- Wrapper around State monad.
newtype GuidCounter a = GC { runGC :: State Int a }
deriving (Monad)
guid :: State Int Int -- Get the next GUID, incrementing the counter.
guid = do n <- get guid :: GuidCounter Int
put (n+1) guid = GC $ do n <- get
return n put (n + 1)
return n
rename :: Expr -> Expr
rename expr = evalState (runGC $ rename' id expr) 0
rename' :: (String -> String) -> Expr -> GuidCounter Expr
rename' env expr = rename' env expr =
case expr of case expr of
Range e1 e2 -> do
re1 <- rename' env e1; re2 <- rename' env e2 Range e1 e2 -> Range `liftM` rnm e1
return $ Range re1 re2 `ap` rnm e2
Access e x -> do
re <- rename' env e Access e x -> Access `liftM` rnm e
return $ Access re x `ap` return x
Binop op e1 e2 ->
do let rop = if isLower (head op) || '_' == head op then env op else op Binop op@(h:_) e1 e2 ->
re1 <- rename' env e1; re2 <- rename' env e2 let rop = if isLower h || '_' == h
return $ Binop rop re1 re2 then env op
Lambda x e -> do (rx, env') <- extend env x else op
rename' env' e >>= return . Lambda rx in Binop rop `liftM` rnm e1
App e1 e2 -> do `ap` rnm e2
re1 <- rename' env e1; re2 <- rename' env e2
return $ App re1 re2 Lambda x e -> do
If e1 e2 e3 -> do (rx, env') <- extend env x
re1 <- rename' env e1; re2 <- rename' env e2; re3 <- rename' env e3 Lambda rx `liftM` rename' env' e
return $ If re1 re2 re3
Lift e es -> do App e1 e2 -> App `liftM` rnm e1
re <- rename' env e `ap` rnm e2
mapM (rename' env) es >>= return . Lift re
Fold e1 e2 e3 -> do If e1 e2 e3 -> If `liftM` rnm e1
re1 <- rename' env e1; re2 <- rename' env e2; re3 <- rename' env e3 `ap` rnm e2
return $ Fold re1 re2 re3 `ap` rnm e3
Async e -> rename' env e >>= return . Async
Lift e es -> Lift `liftM` rnm e
`ap` mapM rnm es
Fold e1 e2 e3 -> Fold `liftM` rnm e1
`ap` rnm e2
`ap` rnm e3
Async e -> Async `liftM` rnm e
Let defs e -> do Let defs e -> do
let (vs,es) = unzip defs let (vs,es) = unzip defs
env' <- foldM (\acc x -> extend acc x >>= return . snd) env vs env' <- foldM (\acc x -> snd `liftM` extend acc x) env vs
es' <- mapM (rename' env') es; re <- rename' env' e es' <- mapM (rename' env') es; re <- rename' env' e
return $ Let (zip (map env' vs) es') re return $ Let (zip (map env' vs) es') re
Var x -> return . Var $ env x Var x -> return . Var $ env x
Data name es -> mapM (rename' env) es >>= return . Data name
Case e cases -> do Data name es -> Data name `liftM` mapM rnm es
re <- rename' env e
mapM (pattern_rename env) cases >>= return . (Case re) Case e cases -> Case `liftM` rnm e
`ap` mapM (patternRename env) cases
_ -> return expr _ -> return expr
where rnm = rename' env
extend :: (String -> String) -> String -> GuidCounter (String, String -> String)
extend env x = do extend env x = do
n <- guid n <- guid
let rx = x ++ "_" ++ show n let rx = x ++ "_" ++ show n
return (rx, (\y -> if y == x then rx else env y)) return (rx, \y -> if y == x then rx else env y)
pattern_extend pattern env = patternExtend :: Pattern -> (String -> String) -> GuidCounter (Pattern, String -> String)
patternExtend pattern env =
case pattern of case pattern of
PAnything -> return (PAnything, env) PAnything -> return (PAnything, env)
PVar x -> extend env x >>= return . first PVar PVar x -> first PVar `liftM` extend env x
PData name ps -> PData name ps ->
foldM f ([],env) ps >>= return . first (PData name . reverse) first (PData name . reverse) `liftM` foldM f ([], env) ps
where f (rps,env') p = do (rp,env'') <- pattern_extend p env' where f (rps,env') p = do (rp,env'') <- patternExtend p env'
return (rp:rps, env'') return (rp:rps, env'')
pattern_rename env (p,e) = do patternRename :: (String -> String) -> (Pattern, Expr) -> GuidCounter (Pattern, Expr)
(rp,env') <- pattern_extend p env patternRename env (p,e) = do
(rp,env') <- patternExtend p env
re <- rename' env' e re <- rename' env' e
return (rp,re) return (rp,re)