@@ -24,8 +24,8 @@ module Asyncly.AsyncT
24 ( AsyncT (..)
24 ( AsyncT (..)
28− , makeAsync
28+-- , makeAsync
@@ -46,7 +46,7 @@ import Control.Monad.Base (MonadBase (..), liftBaseDefault)
46import Control.Monad.Catch (MonadThrow, throwM)
46import Control.Monad.Catch (MonadThrow, throwM)
47import Control.Monad.State (MonadIO (..), MonadPlus (..),
47import Control.Monad.State (MonadIO (..), MonadPlus (..),
48 StateT (..), liftM, runStateT,
48 StateT (..), liftM, runStateT,
49− modify)
49+ get, gets, put, modify)
50import Control.Monad.Trans.Class (MonadTrans (lift))
50import Control.Monad.Trans.Class (MonadTrans (lift))
51import Control.Monad.Trans.Control (ComposeSt, MonadBaseControl (..),
51import Control.Monad.Trans.Control (ComposeSt, MonadBaseControl (..),
52 MonadTransControl (..),
52 MonadTransControl (..),
@@ -60,7 +60,8 @@ import Control.Monad.Trans.Recorder (MonadRecorder(..))
61import Asyncly.Threads
61import Asyncly.Threads
63+--data Step a m = Stop | Yield a (AsyncT m a)
63−newtype AsyncT m a = AsyncT { runAsyncT :: StateT Context m (Maybe a) }
64+--newtype AsyncT m a = AsyncT { runAsyncT :: StateT Context m (Step a m) }
65------------------------------------------------------------------------------
66------------------------------------------------------------------------------
66-- Utilities
67-- Utilities
@@ -76,23 +77,38 @@ dbg _ = return ()
77------------------------------------------------------------------------------
78------------------------------------------------------------------------------
80+stop :: Monad m => AsyncT m a
81+stop = AsyncT . return $ Stop
83+{-# SPECIALIZE runAction :: AsyncT IO a -> StateT Context IO (Step a IO) #-}
84+runAction :: Monad m => AsyncT m a -> StateT Context m (Step a m)
87+ (step, ctx') <- lift $ runStateT (runAsyncT m) ctx
92+{-# SPECIALIZE parallel :: AsyncT IO a -> AsyncT IO a -> StateT Context IO (Step a IO) #-}
96+ -> StateT Context m (Step a m)
100+ Stop -> runAsyncT mb
101+ Yield a mx -> return (Yield a (AsyncT (parallel mx mb)))
79instance MonadAsync m => Monad (AsyncT m) where
103instance MonadAsync m => Monad (AsyncT m) where
80 {-# SPECIALIZE instance Monad (AsyncT IO) #-}
104 {-# SPECIALIZE instance Monad (AsyncT IO) #-}
81− return a = AsyncT . return $ Just a
105+ return a = AsyncT . return $ Yield a stop
86− {-# NOINLINE[1] bind #-}
87− bind = AsyncT $ do
107+ m >>= f = AsyncT $ do
88− modify $ \Context {continuations = fs, ..} ->
108+ step <- runAction m
89− Context {continuations = (unsafeCoerce f) : fs, ..}
91− modify $ \Context {continuations = (_ : fs), ..} ->
92− Context {continuations = fs, ..}
93− case x of
109+ case step of
110+ Stop -> return Stop -- XXX need to wait for the child threads
94− Just y -> runAsyncT $ f y
111+ Yield a ma -> runAsyncT $ (f a) <|> (ma >>= f)
95− Nothing -> return Nothing
97------------------------------------------------------------------------------
113------------------------------------------------------------------------------
98-- Functor
114-- Functor
@@ -132,10 +148,8 @@ instance MonadAsync m => Applicative (AsyncT m) where
133instance MonadAsync m => Alternative (AsyncT m) where
149instance MonadAsync m => Alternative (AsyncT m) where
134 {-# SPECIALIZE instance Alternative (AsyncT IO) #-}
150 {-# SPECIALIZE instance Alternative (AsyncT IO) #-}
135− empty = AsyncT $ return Nothing
151+ empty = stop
136− (<|>) m1 m2 = AsyncT $ do
152+ (<|>) m1 m2 = AsyncT $ parallel m1 m2
137− r <- runAsyncTask False (runAsyncT m1)
138− maybe (runAsyncT m2) (return . Just) r
140instance MonadAsync m => MonadPlus (AsyncT m) where
154instance MonadAsync m => MonadPlus (AsyncT m) where
141 mzero = empty
155 mzero = empty
@@ -162,7 +176,7 @@ instance (Num a, Monad (AsyncT m)) => Num (AsyncT m a) where
162-------------------------------------------------------------------------------
176-------------------------------------------------------------------------------
164instance MonadTrans AsyncT where
178instance MonadTrans AsyncT where
165− lift mx = AsyncT $ lift mx >>= return . Just
179+ lift mx = AsyncT $ lift mx >>= return . (\a -> (Yield a stop))
167instance (MonadBase b m, MonadAsync m) => MonadBase b (AsyncT m) where
181instance (MonadBase b m, MonadAsync m) => MonadBase b (AsyncT m) where
168 liftBase = liftBaseDefault
182 liftBase = liftBaseDefault
@@ -171,6 +185,7 @@ instance (MonadBase b m, MonadAsync m) => MonadBase b (AsyncT m) where
171-- monad-control
185-- monad-control
172-------------------------------------------------------------------------------
186-------------------------------------------------------------------------------
174instance MonadTransControl AsyncT where
189instance MonadTransControl AsyncT where
175 type StT AsyncT a = (Maybe a, Context)
190 type StT AsyncT a = (Maybe a, Context)
176 liftWith f = AsyncT $ StateT $ \s ->
191 liftWith f = AsyncT $ StateT $ \s ->
@@ -186,6 +201,7 @@ instance (MonadBaseControl b m, MonadAsync m) => MonadBaseControl b (AsyncT m) w
186 restoreM = defaultRestoreM
201 restoreM = defaultRestoreM
187 {-# INLINABLE liftBaseWith #-}
202 {-# INLINABLE liftBaseWith #-}
188 {-# INLINABLE restoreM #-}
203 {-# INLINABLE restoreM #-}
190------------------------------------------------------------------------------
206------------------------------------------------------------------------------
191-- Standard transformer instances
207-- Standard transformer instances
@@ -271,11 +287,13 @@ infixr 1 >>|
271-- is not useful and should not be used. Even in an 'Alternative' composition
287-- is not useful and should not be used. Even in an 'Alternative' composition
272-- 'async' is not useful as the last action as the last action always runs in
288-- 'async' is not useful as the last action as the last action always runs in
273-- the current thread.
289-- the current thread.
274async :: MonadAsync m => AsyncT m a -> AsyncT m a
291async :: MonadAsync m => AsyncT m a -> AsyncT m a
275async action = AsyncT $ runAsyncTask True (runAsyncT action)
292async action = AsyncT $ runAsyncTask True (runAsyncT action)
277makeAsync :: MonadAsync m => ((a -> m ()) -> m ()) -> AsyncT m a
294makeAsync :: MonadAsync m => ((a -> m ()) -> m ()) -> AsyncT m a
278makeAsync = AsyncT . makeCont
295makeAsync = AsyncT . makeCont
280-- scatter
298-- scatter
281{-# SPECIALIZE each :: [a] -> AsyncT IO a #-}
299{-# SPECIALIZE each :: [a] -> AsyncT IO a #-}