+newtype State s m a = State (s -> m (s, a))
+
+instance Monad m => Monad (State s m) where
+ return a = State (\s -> return (s, a))
+ State m >>= k = State (\s -> m s >>= \(s', a) -> case k a of State n -> n s')
+ fail str = State (\s -> fail str)
+
+class (Monad m, Monad (t m)) => MonadT t m where
+ lift :: m a -> t m a
+
+instance Monad m => MonadT (State s) m where
+ lift m = State (\s -> m >>= \a -> return (s, a))
+
+runState :: (Monad m) => s -> State s m a -> m a
+runState s (State m) = m s >>= return . snd
+
+type PtrIO = State (Ptr Word8) IO
+
+advance :: Storable a => PtrIO (Ptr a)
+advance = State adv where
+ adv addr = case castPtr addr of { addrCast -> return
+ (addr `plusPtr` sizeOfPointee addrCast, addrCast) }
+
+sizeOfPointee :: (Storable a) => Ptr a -> Int
+sizeOfPointee addr = sizeOf (typeHack addr)
+ where typeHack = undefined :: Ptr a -> a
+
+store :: Storable a => a -> PtrIO ()
+store x = do addr <- advance
+ lift (poke addr x)
+
+load :: Storable a => PtrIO a
+load = do addr <- advance
+ lift (peek addr)