Why can `env` be assigned value two times ?

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? Sincerely! ----- fac n = foldr (*) 1 [1..n] -- View this message in context: http://old.nabble.com/Why-can-%60env%60-be-assigned-value-two-times---tp2635... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

They're two different 'env's, which can be observed by desugaring the do-notation: do env <- liftIO (readIORef envRef) env <- return (filter (\(_id, _) -> _id /= id) env) ... Desugaring do-notation gets us: liftIO (readIORef envRev) >>= \ env -> return (filter (\(_id, _) -> _id /= id) env) >>= \ env -> ... Sometimes people use different names to make this obvious, e.g. do env <- liftIO $ readIORef envRef env' <- return (filter ... env) Also note that you're doing a pure operation here, so you don't need two bindings. You could instead do: do env <- filter (\(_id, _) -> _id /= id) <$> readIORev envRef ... (<$> is from the supremely useful Control.Applicative, and is equivalent to fmap from Functor, or liftM from Monad) or: do env <- liftIO $ readIORef envRef let env' = filter ... env Using let notation here makes it somewhat more obvious that that line doesn't have any side effects. -Ross On Nov 15, 2009, at 2:05 AM, 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?
Sincerely!
----- fac n = foldr (*) 1 [1..n] -- View this message in context: http://old.nabble.com/Why-can-%60env%60-be-assigned-value-two-times---tp2635... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

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

thanks for all your answers ! 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?
Sincerely!
----- fac n = foldr (*) 1 [1..n] -- View this message in context: http://old.nabble.com/Why-can-%60env%60-be-assigned-value-two-times---tp2635... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
participants (3)
-
Brandon S. Allbery KF8NH
-
Ross Mellgren
-
zaxis