coroutine-enumerator 0.1 → 0.1.1
raw patch · 4 files changed
+110/−109 lines, 4 filesdep ~monad-coroutinePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: monad-coroutine
API changes (from Hackage documentation)
Files
- Control/Monad/Coroutine/Enumerator.hs +3/−3
- Test/TestEnumerator.hs +103/−0
- TestEnumerator.hs +0/−102
- coroutine-enumerator.cabal +4/−4
Control/Monad/Coroutine/Enumerator.hs view
@@ -31,7 +31,7 @@ import qualified Data.Enumerator as 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@@ -45,7 +45,7 @@ streamChunk (b, EOF) = (b, []) streamChunk (b, Chunks chunk) = (b, chunk) --- | Converts a 'Coroutine' parameterized with the 'Await' [x] functor, treating an ampty input chunk as 'EOF', into an+-- | Converts a 'Coroutine' parameterized with the 'Await' [x] functor, treating an empty input chunk as 'EOF', into an -- 'Iteratee'. coroutineIteratee :: Monad m => Coroutine (Await [a]) m (Either SomeException (b, [a])) -> Iteratee a m b coroutineIteratee = streamCoroutineIteratee . convert . liftM (either Left (Right . \(b, chunk)-> (b, Chunks chunk)))@@ -81,5 +81,5 @@ -- | Converts a 'Coroutine' parameterized with the 'Yield' functor into an 'Enumerator'. coroutineEnumerator :: Monad m => Coroutine (Yield [a]) m b -> Enumerator a m c coroutineEnumerator c step@(Enumerator.Continue cont) = Iteratee (resume c >>= either feed (const $ return step))- where feed (Yield chunk c) = runIteratee (cont (Chunks chunk)) >>= runIteratee . coroutineEnumerator c+ where feed (Yield chunk c') = runIteratee (cont (Chunks chunk)) >>= runIteratee . coroutineEnumerator c' coroutineEnumerator _ step = Enumerator.returnI step
+ Test/TestEnumerator.hs view
@@ -0,0 +1,103 @@+{- + Copyright 2010-2011 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.Enumerator (Enumerator, Iteratee(..), Stream(..), enumList, enumEOF, ($$), (>==>))+import qualified Data.Enumerator as Enumerator+import qualified Data.Enumerator.List as Enumerator.List+import Data.Functor.Identity (runIdentity)++import Control.Monad.Coroutine+import Control.Monad.Coroutine.Enumerator+import Control.Monad.Coroutine.SuspensionFunctors (Await(Await), Yield(Yield), await, yield, awaitYieldResolver)+import Control.Monad.Parallel+++streamToList :: Await (Stream a) b -> Await [a] b+streamToList (Await cont) = Await (\chunk-> cont $ if null chunk then EOF else Chunks chunk)++listToStream :: Await [a] b -> Await (Stream a) b+listToStream (Await cont) = Await (cont . unChunks)+ where unChunks (Chunks l) = l+ unChunks EOF = []++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 ns)++yieldAll :: Monad m => [Integer] -> Coroutine (Yield [Integer]) m ()+yieldAll = mapM_ yield . List.groupBy (\m n-> m `mod` 10 == n `mod` 10)++sumIteratee :: Monad m => Iteratee Integer m Integer+sumIteratee = Enumerator.List.fold (+) 0++listResolver = awaitYieldResolver{resumeLeft= \(Await c)-> c []}++testSumCI :: Monad m => [Integer] -> m Integer+testSumCI list = liftM (\(Enumerator.Yield s _)-> s) $ + runIteratee ((enumList 10 list >==> enumEOF) $$ coroutineIteratee sumCoroutine)++testSumEC :: MonadParallel m => [Integer] -> m Integer+testSumEC list = liftM (\(Right (s, _), _)-> s) $ + seesaw bindM2 listResolver sumCoroutine (enumeratorCoroutine (enumList 10 list >==> enumEOF))++testSumCE :: Monad m => [Integer] -> m Integer+testSumCE list = liftM (\(Enumerator.Yield s _)-> s) $ + runIteratee ((coroutineEnumerator (yieldAll list) >==> enumEOF) $$ sumIteratee)++testSumIC :: MonadParallel m => [Integer] -> m Integer+testSumIC list = liftM (\(Right (s, _), _)-> s) $ + seesaw bindM2 listResolver (iterateeCoroutine sumIteratee) (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-enumerator <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"+
− TestEnumerator.hs
@@ -1,102 +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.Enumerator (Enumerator, Iteratee(..), Stream(..), enumList, enumEOF, ($$), (>==>))-import qualified Data.Enumerator as Enumerator-import Data.Functor.Identity (runIdentity)--import Control.Monad.Coroutine-import Control.Monad.Coroutine.Enumerator-import Control.Monad.Coroutine.SuspensionFunctors (Await(Await), Yield(Yield), await, yield, awaitYieldResolver)-import Control.Monad.Parallel---streamToList :: Await (Stream a) b -> Await [a] b-streamToList (Await cont) = Await (\chunk-> cont $ if null chunk then EOF else Chunks chunk)--listToStream :: Await [a] b -> Await (Stream a) b-listToStream (Await cont) = Await (cont . unChunks)- where unChunks (Chunks l) = l- unChunks EOF = []--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 ns)--yieldAll :: Monad m => [Integer] -> Coroutine (Yield [Integer]) m ()-yieldAll = mapM_ yield . List.groupBy (\m n-> m `mod` 10 == n `mod` 10)--sumIteratee :: Monad m => Iteratee Integer m Integer-sumIteratee = Enumerator.liftFoldL (+) 0--listResolver = awaitYieldResolver{resumeLeft= \(Await c)-> c []}--testSumCI :: Monad m => [Integer] -> m Integer-testSumCI list = liftM (\(Enumerator.Yield s _)-> s) $ - runIteratee ((enumList 10 list >==> enumEOF) $$ coroutineIteratee sumCoroutine)--testSumEC :: MonadParallel m => [Integer] -> m Integer-testSumEC list = liftM (\(Right (s, _), _)-> s) $ - seesaw bindM2 listResolver sumCoroutine (enumeratorCoroutine (enumList 10 list >==> enumEOF))--testSumCE :: Monad m => [Integer] -> m Integer-testSumCE list = liftM (\(Enumerator.Yield s _)-> s) $ - runIteratee ((coroutineEnumerator (yieldAll list) >==> enumEOF) $$ sumIteratee)--testSumIC :: MonadParallel m => [Integer] -> m Integer-testSumIC list = liftM (\(Right (s, _), _)-> s) $ - seesaw bindM2 listResolver (iterateeCoroutine sumIteratee) (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-enumerator <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-enumerator.cabal view
@@ -1,5 +1,5 @@ Name: coroutine-enumerator-Version: 0.1+Version: 0.1.1 Cabal-Version: >= 1.2 Build-Type: Simple Synopsis: Bridge between the monad-coroutine and enumerator 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-enumerator-Extra-source-files: TestEnumerator.hs+Extra-source-files: Test/TestEnumerator.hs -- Source-repository head -- type: darcs -- location: http://code.haskell.org/SCC/ Library Exposed-Modules: Control.Monad.Coroutine.Enumerator- Build-Depends: base < 5, monad-coroutine >= 0.6 && < 0.7, enumerator >= 0.4 && < 0.5+ Build-Depends: base < 5, monad-coroutine >= 0.6 && < 0.8, enumerator >= 0.4 && < 0.5 GHC-prof-options: -auto-all