packages feed

hstzaar-0.7: src/History.hs

-- Module for undo/redo navigation 
--
-- the history maintains a cursor in a sequence 
--
--  pbv, 2011
module History where
import Prelude hiding (length)
import qualified Prelude (length)


-- | data type for history
data History a = 
    History { back :: [a], 
              front :: [a]
            }  deriving (Eq, Show, Read)
    
-- | initialize history
init :: a -> History a                        
init x = History {back=[x], front=[]}


atStart :: History a -> Bool
atStart = singleton . back 

singleton :: [a] -> Bool
singleton [_] = True
singleton _   = False

atEnd :: History a -> Bool
atEnd = null . front

length :: History a -> Int
length h = Prelude.length (back h) + Prelude.length (front h)

position :: History a -> Int
position h = Prelude.length (back h)


-- | navigate backwards
previous :: History a -> History a
previous h
  = case back h of 
      [x] -> h
      (x:xs) -> History { back = xs, front = x:front h }

-- | navigate forwards
next :: History a -> History a
next h
  = case front h of 
      [] -> h
      (x:xs) -> History { back = x:back h, front = xs }


-- | record at the current point 
-- obliviates next entries
record :: a -> History a -> History a
record x h = History { back = x:back h, front = [] }

-- | get the cursor value
get :: History a -> a
get h = case back h of
          (x:_) -> x
          [] -> error "History.get: no value"