@@ -12,7 +12,7 @@
12module Strands.AsyncT
12module Strands.AsyncT
13 ( AsyncT (..)
13 ( AsyncT (..)
15− , onNothing
15+ , (**>)
@@ -21,14 +21,12 @@ import Control.Applicative (Alternative (..))
21import Control.Monad.Base (MonadBase (..), liftBaseDefault)
21import Control.Monad.Base (MonadBase (..), liftBaseDefault)
22import Control.Monad.Catch (MonadThrow, throwM)
22import Control.Monad.Catch (MonadThrow, throwM)
23import Control.Monad.State (MonadIO (..), MonadPlus (..),
23import Control.Monad.State (MonadIO (..), MonadPlus (..),
24− MonadState (..), StateT (..),
25− liftM, modify, runStateT, when)
24+ StateT (..), liftM, runStateT)
26import Control.Monad.Trans.Class (MonadTrans (lift))
25import Control.Monad.Trans.Class (MonadTrans (lift))
27import Control.Monad.Trans.Control (ComposeSt, MonadBaseControl (..),
26import Control.Monad.Trans.Control (ComposeSt, MonadBaseControl (..),
28 MonadTransControl (..),
27 MonadTransControl (..),
29 defaultLiftBaseWith,
28 defaultLiftBaseWith,
30 defaultRestoreM)
29 defaultRestoreM)
31−import Data.Dynamic (Typeable)
33import Strands.Context
31import Strands.Context
@@ -46,15 +44,6 @@ newtype AsyncT m a = AsyncT { runAsyncT :: StateT Context m (Maybe a) }
46dbg :: Monad m => a -> m ()
44dbg :: Monad m => a -> m ()
47dbg _ = return ()
45dbg _ = return ()
49−-- | If the first parameter is 'Nothing' return the second parameter otherwise
50−-- return the first parameter..
51−onNothing :: Monad m => m (Maybe b) -> m b -> m b
52−onNothing iox iox'= do
58------------------------------------------------------------------------------
47------------------------------------------------------------------------------
60------------------------------------------------------------------------------
49------------------------------------------------------------------------------
@@ -143,135 +132,6 @@ instance (MonadBaseControl b m, MonadIO m) => MonadBaseControl b (AsyncT m) wher
143instance MonadThrow m => MonadThrow (AsyncT m) where
132instance MonadThrow m => MonadThrow (AsyncT m) where
144 throwM e = lift $ throwM e
133 throwM e = lift $ throwM e
146−------------------------------------------------------------------------------
147−-- * Extensible State: Session Data Management
148−------------------------------------------------------------------------------
150−-- | Retrieve a previously stored data item of the given data type from the
151−-- monad state. The data type to retrieve is implicitly determined from the
152−-- requested type context.
153−-- If the data item is not found, an 'empty' value (a void event) is returned.
154−-- Remember that an empty value stops the monad computation. If you want to
155−-- print an error message or a default value in that case, you can use an
156−-- 'Alternative' composition. For example:
158−-- > getSData <|> error "no data"
159−-- > getInt = getSData <|> return (0 :: Int)
160−getSData :: (Monad m, Typeable a) => AsyncT m a
161−getSData = AsyncT getData
163−-- | 'setSData' stores a data item in the monad state which can be retrieved
164−-- later using 'getData' or 'getSData'. Stored data items are keyed by their
165−-- data type, and therefore the data type must be 'Typeable' and only one item
166−-- of a given type can be stored. A newtype wrapper can be used to distinguish
167−-- two data items of the same type when required.
170−-- import Control.Monad.IO.Class (liftIO)
171−-- import Transient.Base
172−-- import Data.Typeable
174−-- data Person = Person
177−-- } deriving Typeable
180−-- setSData $ Person "Alberto" 55
181−-- Person name age <- getSData
182−-- liftIO $ print (name, age)
184−setSData :: (Monad m, Typeable a) => a -> AsyncT m ()
185−setSData x = AsyncT $ setData x >> return (Just ())
187−-- | Accepts a function that takes the current value of the stored data type
188−-- and returns the modified value. If the function returns 'Nothing' the value
189−-- is deleted otherwise updated.
190−modifySData :: (Monad m, Typeable a) => (Maybe a -> Maybe a) -> AsyncT m ()
191−modifySData x = AsyncT $ modifyData x >> return (Just ())
193−-- | Delete the data item of the given type from the monad state.
194−delSData :: (Monad m, Typeable a) => a -> AsyncT m ()
195−delSData x = AsyncT $ delData x >> return (Just ())
197−------------------------------------------------------------------------------
198−-- MonadState for AsyncT m
199−------------------------------------------------------------------------------
201−instance (Monad m, Monad (AsyncT m)) => MonadState Context (AsyncT m) where
202− get = AsyncT $ get >>= return . Just
203− put x = AsyncT $ put x >> return (Just ())
204− state f = AsyncT $ do
211−-- | Run an action, if the result is a void action undo any state changes
212−-- that it might have caused.
213−try :: MonadIO m => AsyncT m a -> AsyncT m a
216− mx <|> (modify (\s -> s { mfData = sd }) >> empty)
218−-- | Executes the computation and reset the state either if it fails or not
219−sandbox :: MonadIO m => AsyncT m a -> AsyncT m a
222− mx <*** modify (\s ->s { mfData = sd})
225−------------------------------------------------------------------------------
227−------------------------------------------------------------------------------
230−-- | Run the closure (the 'x' in 'x >>= f') of the current bind operation.
231−runClosure :: EventF -> StateM m (Maybe a)
232−runClosure EventF { xcomp = x } = runAsyncT (unsafeCoerce x)
234−-- | Run the continuation (the 'f' in 'x >>= f') of the current bind operation with the current state.
235−runContinuation :: MonadIO m => EventF -> a -> StateM m (Maybe b)
236−runContinuation EventF { fcomp = fs } =
237− runAsyncT . (compose $ (unsafeCoerce fs))
239−data Backtrack b = Show b => Backtrack
240− { backtracking :: Maybe b
241− , backStack :: [EventF]
244−backStateOf :: (Monad m, Show a) => a -> m (Backtrack a)
245−backStateOf reason = return $ Backtrack (Nothing `asTypeOf` (Just reason)) []
247−-- | Start the undo process for the given undo track id. Performs all the undo
248−-- actions registered till now in reverse order. An undo action can use
249−-- 'forward' to stop the undo process and resume forward execution. If there
250−-- are no more undo actions registered execution stops and a 'stop' action is
253−back :: (MonadIO m, Typeable b, Show b) => b -> AsyncT m a
254−back reason = AsyncT $ do
255− bs <- getData `onNothing` backStateOf reason
260− goBackt (Backtrack _ [] )= return Nothing
261− goBackt (Backtrack _ (stack@(first : bs)) )= do
262− (setData $ Backtrack (Just reason) stack)
264− mr <- runClosure first
266− Backtrack b _ <- getData `onNothing` backStateOf reason
268− Nothing -> return empty
270− Nothing -> runContinuation first x
271− justreason -> goBackt $ Backtrack justreason bs
275------------------------------------------------------------------------------
135------------------------------------------------------------------------------
276-- More operators, instances
136-- More operators, instances
277------------------------------------------------------------------------------
137------------------------------------------------------------------------------
@@ -346,12 +206,12 @@ infixr 1 <**, **>
346-- | Run @m a@ discarding its result before running @m b@.
206-- | Run @m a@ discarding its result before running @m b@.
347(**>) :: Monad m => AsyncT m a -> AsyncT m b -> AsyncT m b
207(**>) :: Monad m => AsyncT m a -> AsyncT m b -> AsyncT m b
348(**>) x y = AsyncT $ do
208(**>) x y = AsyncT $ do
349− runAsyncT x
209+ _ <- runAsyncT x
350 runAsyncT y
210 runAsyncT y
352-- | Run @m b@ discarding its result, after the whole task set @m a@ is done.
212-- | Run @m b@ discarding its result, after the whole task set @m a@ is done.
353(<**) :: Monad m => AsyncT m a -> AsyncT m b -> AsyncT m a
213(<**) :: Monad m => AsyncT m a -> AsyncT m b -> AsyncT m a
354(<**) ma mb = AsyncT $ do
214(<**) ma mb = AsyncT $ do
355 a <- runAsyncT ma
215 a <- runAsyncT ma
356− runAsyncT mb
216+ _ <- runAsyncT mb