Funny that it turns out slightly longer when re-using more code due to syntactic artifacts. Monad comprehensions (recently restored to GHC via an extension) would resolve that.
The eval throwing away context does not make any sense in retrospect. I think I made it that way because of some ghetto-scoping ideas.
You broke car and cdr somehow (these don't evaluate their arguments anymore), but I have no idea how you did this.
This was mostly a training exercise, this is why there is no significant use of monads in there: I simply haven't learned enough about them to feel comfortable using them.
Sorry, that was my fault. I didn't make lambdas evaluate their arguments and I didn't notice this in my code. I.e. car/cdr work correctly, fun doesn't.
If you flip the arguments, you get: Value -> Context -> (Context, Value). The (Context -> (Context, Value)) is actually the State type:
I modified your code to use this type. During the process, I encountered some peculiar things (and factored out some things), see comments in code.https://gist.github.com/950445
Funny that it turns out slightly longer when re-using more code due to syntactic artifacts. Monad comprehensions (recently restored to GHC via an extension) would resolve that.