on master help sign in
A Monoid instance for Source
commit2de759d960fa3ce55fc6c2a8aae1d49db1438b06 authorMichael <michael@snoyman.com> dateFri 9 Dec 2011, 11:17 (15 years ago) parent0321607
2 files changed+33−3
conduit/Data/Conduit.hs+26 conduit/sum.hs+7−3
conduit/Data/Conduit.hs+26
@@ -30,6 +30,7 @@ import qualified Data.IORef as I
3030import Data.Typeable (Typeable)
3131import Control.Monad (liftM)
3232import Control.Applicative (Applicative (..))
33+import Data.Monoid (Monoid (mempty, mappend, mconcat))
3334
3435data Stream a = EOF | Chunks [a]
3536 deriving Show
@@ -48,6 +49,31 @@ data SourceInside m a = SourceInside
4849 , sourcePush :: [a] -> ResourceT m ()
4950 }
5051newtype 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]
55+ mconcat [] = mempty
56+ mconcat (Source mnext:rest0) = Source $ do
57+ next0 <- mnext
58+ istate <- liftBase $ I.newIORef $ Just (next0, rest0)
59+ unSource $ mkSource $ go istate
60+ where
61+ go istate = do
62+ state <- liftBase $ I.readIORef istate
63+ case state of
64+ Nothing -> return EOF
65+ Just (next, rest) -> do
66+ stream <- sourcePull next
67+ case stream of
68+ EOF ->
69+ case rest of
70+ Source a:as -> do
71+ a' <- a
72+ liftBase $ I.writeIORef istate $ Just (a', as)
73+ go istate
74+ [] -> do
75+ liftBase $ I.writeIORef istate Nothing
76+ return EOF
5177
5278type SinkInsideData a m b = Stream a -> ResourceT m (SinkResult a b)
5379data SinkInside a m b =
conduit/sum.hs+7−3
@@ -1,12 +1,16 @@
11import Data.Conduit
22import qualified Data.Conduit.List as CL
33import Control.Monad.Trans.Resource
4+import Data.Monoid (mappend)
45
56main :: IO ()
67main = do
7− runResourceT (CL.fromList [1..10] $= CL.concatMap (replicate 2) $$ do
8− _ <- CL.take 10
9− CL.map (* 2) =$ sum') >>= putStrLn
8+ runResourceT (
9+ (CL.fromList [1..5] `mappend` CL.fromList [6..10])
10+ $= CL.concatMap (replicate 2)
11+ $$ do
12+ _ <- CL.take 10
13+ CL.map (* 2) =$ sum') >>= putStrLn
1014
1115sum' :: Sink Int IO String
1216sum' = fmap show $ CL.fold (+) 0