@@ -30,6 +30,7 @@ import qualified Data.IORef as I
30import Data.Typeable (Typeable)
30import Data.Typeable (Typeable)
31import Control.Monad (liftM)
31import Control.Monad (liftM)
32import Control.Applicative (Applicative (..))
32import Control.Applicative (Applicative (..))
33+import Data.Monoid (Monoid (mempty, mappend, mconcat))
34data Stream a = EOF | Chunks [a]
35data Stream a = EOF | Chunks [a]
35 deriving Show
36 deriving Show
@@ -48,6 +49,31 @@ data SourceInside m a = SourceInside
48 , sourcePush :: [a] -> ResourceT m ()
49 , sourcePush :: [a] -> ResourceT m ()
50newtype Source m a = Source { unSource :: ResourceT m (SourceInside m a) }
51newtype Source m a = Source { unSource :: ResourceT m (SourceInside m a) }
52+instance MonadBaseControl IO m => Monoid (Source m a) where
53+ mempty = mkSource $ return EOF
54+ mappend a b = mconcat [a, b]
56+ mconcat (Source mnext:rest0) = Source $ do
58+ istate <- liftBase $ I.newIORef $ Just (next0, rest0)
59+ unSource $ mkSource $ go istate
62+ state <- liftBase $ I.readIORef istate
64+ Nothing -> return EOF
65+ Just (next, rest) -> do
66+ stream <- sourcePull next
72+ liftBase $ I.writeIORef istate $ Just (a', as)
75+ liftBase $ I.writeIORef istate Nothing
52type SinkInsideData a m b = Stream a -> ResourceT m (SinkResult a b)
78type SinkInsideData a m b = Stream a -> ResourceT m (SinkResult a b)
53data SinkInside a m b =
79data SinkInside a m b =