Side note: this is one area where functional programming languages can really shine. In a pure functional language, all data structures are "persistent", meaning that all previous versions hang around as long as you keep a reference to them. All you need to do is push them on a stack and you have built-in undo support for any operation in the language. If functional languages supported SoftReferences (to my knowledge, none of the pure ones do), you could even have the garbage collector eat the bottom of the undo stack transparently.
In Haskell you could hide this in a monad: it'd act like the State monad, but with an additional action to "undo" that just pops the stack and restores the state. You could also put some special processing in the get/set actions to handle things like folding transparently.
In particular, you can hide a bounded stack in a State monad, so you could prevent the thing from leaking unbounded memory without any garbage collector magic at all. I guess it would be nice if you could bound the total heap rather than one particular stack in your program, but I don't think that in practice that would justify the added complexity in the garbage collector. It would be interesting, though, and that has been known in the past to be sufficient reason for people to try and extend Haskell...
In Haskell you could hide this in a monad: it'd act like the State monad, but with an additional action to "undo" that just pops the stack and restores the state. You could also put some special processing in the get/set actions to handle things like folding transparently.