hunk ./Collaborate.hs 160 +-- Comprehensize Undo + +{- + +Similar to simple undo, we shift the operation we want to undo to the +end, then take it's inverse. However, when checking for conflicts, we +also check if the conflicting patch is later reversed. + +In the paper, this is done by having a pointer to the undo patch which +is mutated when the patch is undone. We would prefer a method which +does not require mutation. + +The paper also assumes we can identify patches by pointer +comparison. We do not want to do that either. + +One solution to the second problem would be to create an id for each +history item (which could be useful in the UI as well). We would then +have the undoneBy field use the history item number instead of a pointer. + +Instead of having a pointer we could maintain a separate assoc list of +actions which been undone. + +Could we use a graph instead? + +let's undo c + +a -> b -> c -> d -> e + \ -> d' -> e' + +then do f and redo c + +a -> b -> c -> d -> e + \ -> d' -> e' -> f + +the graph stuff is not the same. if we undo and redo a patch several +times in a row, that is not recorded in the graph, but is in the list +form. + +Hrm, seems like a sequence might be in order. Sequence supports fast +append, plus an update feature. + + + +a -> b -> c -> d -> e + \ -> d -> e -> ~c + +For now, we can just be optimistic that the conflicted action was +later undone and communte the conflicted patch until it meets its +undoing. We can detect the undoing by inverted the patch and checking +for equality since, A ~A = id + +-} +