Bohtvaroh

Group 'succ' with auto-carry

Jul 14th, 2012
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Control.Monad.Trans.State.Lazy
  2.  
  3. groupSuccWithCarry :: (Bounded a, Enum a, Ord a) => [a] -> [a]
  4. groupSuccWithCarry (h : t) = let (carry, h') = succWithCarry h
  5.                             in h' : evalState (carryOver t) carry
  6.  
  7. succWithCarry :: (Bounded a, Enum a, Ord a) => a -> (Bool, a)
  8. succWithCarry x = let overflow = x == maxBound
  9.                   in (overflow, if overflow then minBound else succ x)
  10.  
  11. carryOver :: (Bounded a, Enum a, Monad m, Ord a) => [a] -> StateT Bool m [a]
  12. carryOver = mapM (\x -> do carry <- get
  13.                            let (carry', x') = if carry then succWithCarry x else (False, x)
  14.                            put carry'
  15.                           return $ x')
Advertisement
Add Comment
Please, Sign In to add comment