To take a concrete example, consider the undo-redo mechanism in a text editor. It seems natural to create a list of objects with each object representing the action that can be undone or redone, and a pointer to the most recent action object. Undoing executes the 'undo' method and moves the pointer to the previous action. Redoing moves the pointer to the next action and calls it's 'redo' method.
You would have a 'delete text' type of action which knows how to remove a particular chunk of text and put it back. You would have a 'change text colour' action which knows how to change text to a particular colour and revert back. You might have an 'insert jpeg' action which knows how to add a picture and remove it from the document.
Crucially, each action object in the list should encapsulate it's data and behaviour. It makes the undo-redo framework so much simpler if the framework knows nothing about each type of action, besides the fact that each action object has some kind of undo and redo behaviour.
I cannot see how you could get a simpler design without OO principles such as coupling the data and methods of each type of action, or without hiding the implementation details of each action from the undo-redo framework.