coroutine-iteratee 0.1 → 0.1.1
raw patch · 4 files changed
+112/−112 lines, 4 filesdep ~iterateedep ~monad-coroutinePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: iteratee, monad-coroutine
API changes (from Hackage documentation)
Files
- Control/Monad/Coroutine/Iteratee.hs +12/−12
- Test/TestIteratee.hs +96/−0
- TestIteratee.hs +0/−96
- coroutine-iteratee.cabal +4/−4
Control/Monad/Coroutine/Iteratee.hs view
@@ -24,15 +24,15 @@ ) where -import Control.Monad (liftM, unless)+import Control.Monad (liftM) import Control.Exception.Base (SomeException) import Data.Monoid (Monoid, mconcat) -import Data.Iteratee.Base (Iteratee(..), Stream(..), icont, idone, idoneM, run)+import Data.Iteratee.Base (Iteratee(..), Stream(..), icont, idone, idoneM) import Data.Iteratee.Iteratee (Enumerator) import Control.Monad.Coroutine-import Control.Monad.Coroutine.SuspensionFunctors (Await(Await), Yield(Yield), await, yield)+import Control.Monad.Coroutine.SuspensionFunctors (Await(Await), Yield(Yield), yield) -- | Converts an 'Iteratee' into a 'Coroutine' parameterized with the 'Await' [x] functor. The coroutine treats an empty@@ -44,7 +44,7 @@ endOnEmptyChunk cont [] = cont (EOF Nothing) endOnEmptyChunk cont xs = cont (Chunk $ mconcat xs) streamChunk (Left e) = Left e- streamChunk (Right (b, EOF (Just e))) = Left e+ streamChunk (Right (_, EOF (Just e))) = Left e streamChunk (Right (b, EOF Nothing)) = Right (b, []) streamChunk (Right (b, Chunk chunk)) = Right (b, [chunk]) @@ -56,33 +56,33 @@ where convert cort = Coroutine {resume= resume cort >>= return . either (Left . convertSuspension) Right} convertSuspension (Await cont) = Await (ignoreEmptyChunks (convert . cont)) ignoreEmptyChunks cont (Chunk chunk) = cont [chunk]- ignoreEmptyChunks cont (EOF e) = cont []+ ignoreEmptyChunks cont EOF{} = cont [] -- | Converts an 'Iteratee' into a 'Coroutine' parameterized with the 'Await' ('Stream' x) functor. iterateeStreamCoroutine :: Monad m => Iteratee s m b -> Coroutine (Await (Stream s)) m (Either SomeException (b, Stream s)) iterateeStreamCoroutine iter = Coroutine{resume= runIter iter convertDone convertContinue} where convertDone b s = return (Right $ Right (b, s))- convertContinue cont (Just e) = return (Right $ Left e)+ convertContinue _ (Just e) = return (Right $ Left e) convertContinue cont Nothing = return (Left $ Await (iterateeStreamCoroutine . cont)) -- | Converts a 'Coroutine' parameterized with the 'Await' functor into an 'Iteratee'. streamCoroutineIteratee :: Monad m => Coroutine (Await (Stream s)) m (Either SomeException (b, Stream s)) -> Iteratee s m b streamCoroutineIteratee c = Iteratee (\done continue-> resume c >>= convertStep done continue)- where convertStep done continue (Left (Await cont)) = continue (streamCoroutineIteratee . cont) Nothing- convertStep done continue (Right (Left e)) = - continue (const $ streamCoroutineIteratee $ return (Left e)) (Just e)- convertStep done continue (Right (Right (b, s))) = done b s+ where convertStep _ continue (Left (Await cont)) = continue (streamCoroutineIteratee . cont) Nothing+ convertStep _ continue (Right (Left e)) = continue (const $ streamCoroutineIteratee $ return (Left e)) (Just e)+ convertStep done _ (Right (Right (b, s))) = done b s -- | Converts an 'Enumerator' into a 'Coroutine' parameterized with the 'Yield' functor. enumeratorCoroutine :: Monad m => Enumerator s (Coroutine (Yield [s]) m) () -> Coroutine (Yield [s]) m () enumeratorCoroutine enum = enum (icont step Nothing) >> return ()- where step (Chunk c) = Iteratee (\done continue-> yield [c] >> continue step Nothing)+ where step (Chunk c) = Iteratee (\_ continue-> yield [c] >> continue step Nothing) step s@EOF{} = idone () s -- | Converts a 'Coroutine' parameterized with the 'Yield' functor into an 'Enumerator'. coroutineEnumerator :: (Monad m, Monoid s) => Coroutine (Yield [s]) m b -> Enumerator s m c coroutineEnumerator c i = runIter i idoneM continue- where feed step (Yield chunk c) = coroutineEnumerator c (step (Chunk $ mconcat chunk))+ where feed step (Yield chunk c') = coroutineEnumerator c' (step (Chunk $ mconcat chunk)) continue step Nothing = resume c >>= either (feed step) (const $ return $ step (EOF Nothing))+ continue step e = return (icont step e)
+ Test/TestIteratee.hs view
@@ -0,0 +1,96 @@+{- + Copyright 2010 Mario Blazevic++ This file is part of the Streaming Component Combinators (SCC) project.++ The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public+ License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later+ version.++ SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.++ You should have received a copy of the GNU General Public License along with SCC. If not, see+ <http://www.gnu.org/licenses/>.+-}++-- | The Control.Monad.Coroutine.Enumerator tests.++module Main where++import Control.Exception (assert)+import Control.Exception.Base (SomeException)+import Control.Monad (liftM)+import qualified Data.List as List+import Data.Maybe (fromJust)+import System.Environment (getArgs)++import Debug.Trace++import Data.Iteratee (Enumerator, Iteratee(..), Stream(..))+import Data.Iteratee (enumEof, (>>>))+import qualified Data.Iteratee.ListLike as Iteratee+import Data.Functor.Identity (runIdentity)++import Control.Monad.Coroutine+import Control.Monad.Coroutine.Iteratee+import Control.Monad.Coroutine.SuspensionFunctors (Await(Await), Yield(Yield), await, yield, awaitYieldResolver)+import Control.Monad.Parallel+++sumCoroutine :: Monad m => Coroutine (Await [[Integer]]) m (Either SomeException (Integer, [[Integer]]))+sumCoroutine = sum' 0+ where sum' s = do ns <- await+ if null ns then return (Right (s, [])) else sum' (s + List.sum (List.concat ns))++yieldAll :: Monad m => [Integer] -> Coroutine (Yield [[Integer]]) m ()+yieldAll = mapM_ (yield . (:[])) . List.groupBy (\m n-> m `mod` 10 == n `mod` 10)++listResolver = awaitYieldResolver{resumeLeft= \(Await c)-> c []}++testSumCI :: Monad m => [Integer] -> m Integer+-- testSumCI list = liftM (\(Enumerator.Yield s _)-> s) $+-- runIter =<< ((Iteratee.enumPureNChunk list 10 >>> enumEof) $ coroutineIteratee sumCoroutine)+testSumCI list = do i <- (Iteratee.enumPureNChunk list 10 >>> enumEof) $ coroutineIteratee sumCoroutine+ runIter i (\sum _-> return sum) undefined++testSumEC :: MonadParallel m => [Integer] -> m Integer+testSumEC list = liftM (\(Right (s, _), _)-> s) $ + seesaw bindM2 listResolver sumCoroutine (enumeratorCoroutine (Iteratee.enumPureNChunk list 10 + >>> enumEof))++testSumCE :: Monad m => [Integer] -> m Integer+-- testSumCE list = liftM (\(Enumerator.Yield s _)-> s) $ +-- runIter =<< ((coroutineEnumerator (yieldAll list) >>> enumEof) $ Iteratee.sum)+testSumCE list = do i <- (coroutineEnumerator (yieldAll list) >>> enumEof) $ Iteratee.sum+ runIter i (\sum _-> return sum) undefined++testSumIC :: MonadParallel m => [Integer] -> m Integer+testSumIC list = liftM (\(Right (s, _), _)-> s) $ + seesaw bindM2 listResolver (iterateeCoroutine Iteratee.sum) (yieldAll list)++testSum list = do s1 <- testSumCI list+ s2 <- testSumEC list+ s3 <- testSumCE list+ s4 <- testSumIC list+ assert (s1 == s2 && s2 == s3 && s3 == s4) (return s4)++main = do args <- getArgs+ if List.length args /= 4+ then putStr help+ else do let [taskName, monad, size, coroutineCount] = args+ task :: MonadParallel m => m Integer+ task = case taskName of "sum" -> testSum [1 .. read size]+ _ -> error (help ++ "Bad task.")+ result <- case monad of "Maybe" -> return $ fromJust task+ "[]" -> return $ List.head task+ "Identity" -> return $ runIdentity task+ "IO" -> task+ _ -> error (help ++ "Bad monad.")+ print result++help = "Usage: test-iteratee <task> <monad> <size> <coroutines>?\n"+ ++ " where <task> is 'sum',\n"+ ++ " <monad> is 'Identity', 'Maybe', '[]', or 'IO',\n"+ ++ " <size> is the size of the task,\n"+ ++ " and <coroutines> is the number of coroutines to employ.\n"
− TestIteratee.hs
@@ -1,96 +0,0 @@-{- - Copyright 2010 Mario Blazevic-- This file is part of the Streaming Component Combinators (SCC) project.-- The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public- License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later- version.-- SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.-- You should have received a copy of the GNU General Public License along with SCC. If not, see- <http://www.gnu.org/licenses/>.--}---- | The Control.Monad.Coroutine.Enumerator tests.--module Main where--import Control.Exception (assert)-import Control.Exception.Base (SomeException)-import Control.Monad (liftM)-import qualified Data.List as List-import Data.Maybe (fromJust)-import System.Environment (getArgs)--import Debug.Trace--import Data.Iteratee (Enumerator, Iteratee(..), Stream(..))-import Data.Iteratee (enumEof, (>>>))-import qualified Data.Iteratee.ListLike as Iteratee-import Data.Functor.Identity (runIdentity)--import Control.Monad.Coroutine-import Control.Monad.Coroutine.Iteratee-import Control.Monad.Coroutine.SuspensionFunctors (Await(Await), Yield(Yield), await, yield, awaitYieldResolver)-import Control.Monad.Parallel---sumCoroutine :: Monad m => Coroutine (Await [[Integer]]) m (Either SomeException (Integer, [[Integer]]))-sumCoroutine = sum' 0- where sum' s = do ns <- await- if null ns then return (Right (s, [])) else sum' (s + List.sum (List.concat ns))--yieldAll :: Monad m => [Integer] -> Coroutine (Yield [[Integer]]) m ()-yieldAll = mapM_ (yield . (:[])) . List.groupBy (\m n-> m `mod` 10 == n `mod` 10)--listResolver = awaitYieldResolver{resumeLeft= \(Await c)-> c []}--testSumCI :: Monad m => [Integer] -> m Integer--- testSumCI list = liftM (\(Enumerator.Yield s _)-> s) $--- runIter =<< ((Iteratee.enumPureNChunk list 10 >>> enumEof) $ coroutineIteratee sumCoroutine)-testSumCI list = do i <- (Iteratee.enumPureNChunk list 10 >>> enumEof) $ coroutineIteratee sumCoroutine- runIter i (\sum _-> return sum) undefined--testSumEC :: MonadParallel m => [Integer] -> m Integer-testSumEC list = liftM (\(Right (s, _), _)-> s) $ - seesaw bindM2 listResolver sumCoroutine (enumeratorCoroutine (Iteratee.enumPureNChunk list 10 - >>> enumEof))--testSumCE :: Monad m => [Integer] -> m Integer--- testSumCE list = liftM (\(Enumerator.Yield s _)-> s) $ --- runIter =<< ((coroutineEnumerator (yieldAll list) >>> enumEof) $ Iteratee.sum)-testSumCE list = do i <- (coroutineEnumerator (yieldAll list) >>> enumEof) $ Iteratee.sum- runIter i (\sum _-> return sum) undefined--testSumIC :: MonadParallel m => [Integer] -> m Integer-testSumIC list = liftM (\(Right (s, _), _)-> s) $ - seesaw bindM2 listResolver (iterateeCoroutine Iteratee.sum) (yieldAll list)--testSum list = do s1 <- testSumCI list- s2 <- testSumEC list- s3 <- testSumCE list- s4 <- testSumIC list- assert (s1 == s2 && s2 == s3 && s3 == s4) (return s4)--main = do args <- getArgs- if List.length args /= 4- then putStr help- else do let [taskName, monad, size, coroutineCount] = args- task :: MonadParallel m => m Integer- task = case taskName of "sum" -> testSum [1 .. read size]- _ -> error (help ++ "Bad task.")- result <- case monad of "Maybe" -> return $ fromJust task- "[]" -> return $ List.head task- "Identity" -> return $ runIdentity task- "IO" -> task- _ -> error (help ++ "Bad monad.")- print result--help = "Usage: test-iteratee <task> <monad> <size> <coroutines>?\n"- ++ " where <task> is 'sum',\n"- ++ " <monad> is 'Identity', 'Maybe', '[]', or 'IO',\n"- ++ " <size> is the size of the task,\n"- ++ " and <coroutines> is the number of coroutines to employ.\n"
coroutine-iteratee.cabal view
@@ -1,5 +1,5 @@ Name: coroutine-iteratee-Version: 0.1+Version: 0.1.1 Cabal-Version: >= 1.2 Build-Type: Simple Synopsis: Bridge between the monad-coroutine and iteratee packages.@@ -12,16 +12,16 @@ License: GPL License-file: LICENSE.txt-Copyright: (c) 2010 Mario Blazevic+Copyright: (c) 2010-2011 Mario Blazevic Author: Mario Blazevic Maintainer: blamario@yahoo.com Homepage: http://trac.haskell.org/SCC/wiki/coroutine-iteratee-Extra-source-files: TestIteratee.hs+Extra-source-files: Test/TestIteratee.hs -- Source-repository head -- type: darcs -- location: http://code.haskell.org/SCC/ Library Exposed-Modules: Control.Monad.Coroutine.Iteratee- Build-Depends: base < 5, monad-coroutine >= 0.6 && < 0.7, iteratee >= 0.4 && < 0.7+ Build-Depends: base < 5, monad-coroutine >= 0.6 && < 0.8, iteratee >= 0.4 && < 0.9 GHC-prof-options: -auto-all