Skip to content

Instantly share code, notes, and snippets.

@amnn
Last active December 19, 2015 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amnn/5940337 to your computer and use it in GitHub Desktop.
Save amnn/5940337 to your computer and use it in GitHub Desktop.
Dirty Buffer Indicator with Undo/Redo support.
module Undo where
data Op = Edit | Undo | Redo | Load | Save deriving (Eq, Show)
type Str = [Op]
type State = (Int, Int, Int) -- ( Save point, Edit distance, Undo displacement )
valid :: State -> Bool
valid (s,e,u) = s >= 0 && e >= 0 && u <= 0 && s <= e && e+u >= 0
step :: State -> Op -> State
step (s,e,u) op = case op of
Load -> ( 0 , 0 , 0 )
Save -> ( e+u , e , u )
Edit -> ( s , e+1 , 0 )
Undo -> ( s , e , u-1 )
Redo -> ( s , e , u+1 )
indicator :: Str -> Bool
indicator ops = let (s,e,u) = foldl step (0,0,0) ops in s /= e+u
testcases :: [(Str,Bool)]
testcases =
[
( [Load, Edit, Save, Undo, Edit] , True ),
( [Load] , False ),
( [Load, Edit, Edit, Undo, Save] , False ),
( [Load, Edit, Save, Undo, Redo] , False ),
( [Load, Edit, Save, Edit] , True ),
( [Load, Edit, Save, Undo] , True )
]
test :: Eq b => (a -> b) -> [(a,b)] -> Bool
test f xs = map (f . fst) xs == map snd xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment