-- | Apply a function using the current state that returns a value and modifies
-- the state.
getsModify :: (s -> (a, s)) -> State s a
getsModify f = do
    (a, s') <- gets f
    put s' >> return a


-- | Run an 'Async' non-terminating action giving some result to a caller
-- continuation.
--
-- Example:
--
--     (handle, res) <- runAsync $ \yield -> do
--        print "This happens in an asynchronous thread"
--        yield 14
--        threadDelay 10000000
--        return 42
--
--      print res             -- 14, immediately
--      wait handle >>= print -- 42, after 10s
getsModify :: (s -> (a, s)) -> State s a
getsModify f = do
    (a, s') <- gets f
    put s' >> return a


-- | Run an 'Async' non-terminating action giving some result to a caller
-- continuation.
--
-- Example:
--
--     (handle, res) <- runAsync $ \yield -> do
--        print "This happens in an asynchronous thread"
--        yield 14
--        threadDelay 10000000
--        return 42
--
--      print res             -- 14, immediately
--      wait handle >>= print -- 42, after 10s
getsModify f = do
    (a, s') <- gets f
    put s' >> return a


-- | Run an 'Async' non-terminating action giving some result to a caller
-- continuation.
--
-- Example:
--
--     (handle, res) <- runAsync $ \yield -> do
--        print "This happens in an asynchronous thread"
--        yield 14
--        threadDelay 10000000
--        return 42
--
--      print res             -- 14, immediately
--      wait handle >>= print -- 42, after 10s