
On Nov 15, 2009, at 02:05 , zaxis wrote:
defineVar :: Env -> (Id, Val) -> IOThrowsError Val defineVar envRef (id, val) = do { env <- liftIO $ readIORef envRef; env <- return $ filter (\(_id, _) -> _id/=id) env; -- clear the current scope valRef <- liftIO $ newIORef val; liftIO $ writeIORef envRef $ ((id, valRef):env); return val; }
In haskell, the variable canot change its value , right? If so, why can the `env` be assigned value twice?
Because they're not really the same variable; they're separate lambda bindings. If you translate the "do" syntax to the underlying "bind" syntax, you get something like:
defineVar envRef (id,val) = liftIO (readIORef envRef) >>= \env -> return (filter (\(_id,_) -> _id /= id) env) >>= \env -> liftIO (newIORef val) >> liftIO (writeIORef envRef ((id,valRef):env)) >> return val
So you're shadowing (hiding) the original "env" when you reuse the name. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH