Derek Elkins wrote: > The following code works fine for me, so it seems you are missing some > details that may help. > [...snip code...]
Thank you! Indeed I did simplify the code when writing the message -- because I thought that those other bits could not possibly be at fault... ;-) *trying out many changes to my own code and yours* Ok, I finally found it. What actually made the difference was the case for variables: Your version is > eval (Var x) = gets (fromJust . M.lookup x) which is suitably lazy, whereas mine was (more or less) > eval e@(Var name) = do > env <- ask > case M.lookup name env of > Nothing -> do > -- undefined variable reference > warning ("reference to undefined variable " ++ show name) > let val = Data "" > modify (M.insert name val) > return val > Just val -> return val Note that whatever I do in the 'Nothing' case is irrelevant, your code with the Var case replaced by > eval e@(Var name) = do > env <- ask > case M.lookup name env of > Just val -> return val loops as well. My problem is that I still don't understand why this is so! I know of course that pattern matching is strict, but I thought this should be ok here, since I evaluate the declarations _before_ the body, so when evaluation of the body demands the variable, it will be defined. What am I missing? Cheers Ben _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe