iteratee 0.8.9.4 → 0.8.9.5
raw patch · 3 files changed
+3/−333 lines, 3 filesdep ~ListLike
Dependency ranges changed: ListLike
Files
- iteratee.cabal +3/−4
- tests/fusion.hs +0/−95
- tests/fusion2.hs +0/−234
iteratee.cabal view
@@ -1,5 +1,5 @@ name: iteratee-version: 0.8.9.4+version: 0.8.9.5 synopsis: Iteratee-based I/O description: The Iteratee monad provides strict, safe, and functional I/O. In addition@@ -46,7 +46,7 @@ build-depends: base >= 3 && < 6,- ListLike >= 3.0 && < 4,+ ListLike >= 3.0 && < 5, MonadCatchIO-transformers > 0.2 && < 0.4, monad-control == 0.3.* , bytestring >= 0.9 && < 0.11,@@ -80,7 +80,6 @@ if impl(ghc >= 6.8) ghc-options: -fwarn-tabs - source-repository head- type: darcs+ type: git location: http://www.tiresiaspress.us/haskell/iteratee
− tests/fusion.hs
@@ -1,95 +0,0 @@-module Main where--import Data.Iteratee as I-import Criterion.Main-import Control.Monad.Identity---runner- :: Enumeratee [Int] xs Identity a- -> [Int]- -> Iteratee xs Identity a- -> a-runner etee xs iter =- runIdentity $ enumPureNChunk xs 5 (joinI $ etee iter) >>= I.run---- test fusion of enumeratee/iteratee composition-runner2- :: Enumeratee [Int] xs Identity a- -> [Int]- -> Iteratee xs Identity a- -> a-runner2 etee xs iter =- runIdentity $ enumPureNChunk xs 5 (etee =$ iter) >>= I.run---- test fusion of enumerator/enumeratee composition-runner3- :: Enumeratee [Int] xs Identity a- -> [Int]- -> Iteratee xs Identity a- -> a-runner3 etee xs iter =- runIdentity $ (enumPureNChunk xs 5 $= etee) iter >>= I.run--m2 :: Enumeratee [Int] [Int] Identity a-m2 = mapChunks id ><> mapChunks (map (+1))-{-# INLINE m2 #-}--m3 :: Enumeratee [Int] [Int] Identity a-m3 = mapChunks id ><> mapChunks (map (+1)) ><> I.filter (even)-{-# INLINE m3 #-}--m4 :: Enumeratee [Int] [Int] Identity a-m4 = m2 ><> m2--m10 :: Enumeratee [Int] [Int] Identity a-m10 = m3 ><> m2 ><> m3 ><> m2--m' :: Enumeratee [a] [a] Identity x-m' = convStream (getChunk)-{-# INLINE m' #-}--m'2 :: Num a => Enumeratee [a] [a] Identity x-m'2 = convStream (liftM (map (+1)) getChunk)-{-# INLINE m'2 #-}--fusedMap :: Iteratee [Int] Identity a -> a-fusedMap = runner m2 [1..100]--fusedMap' :: Iteratee [Int] Identity a -> a-fusedMap' = runner (m2 ><> m') [1..100]--fusedMap'2 :: Iteratee [Int] Identity a -> a-fusedMap'2 = runner (m2 ><> m' ><> m') [1..100]--fusedMap3 :: Iteratee [Int] Identity a -> a-fusedMap3 = runner m3 [1..100]--fusedMap4 :: Iteratee [Int] Identity a -> a-fusedMap4 = runner m4 [1..100]--fusedMap10 :: Iteratee [Int] Identity a -> a-fusedMap10 = runner m10 [1..100]--fusionBenches :: [Benchmark]-fusionBenches =- [ bench "mapChunks/mapChunks fusion" $ whnf fusedMap I.sum- , bench "mapChunks/filter fusion" $ whnf fusedMap3 I.sum- , bench "nested mapChunks/mapChunks fusion" $ whnf fusedMap4 I.sum- , bench "highly nested fusion" $ whnf fusedMap10 I.sum- , bench "mapChunks/mapChunks/convStream" $ whnf fusedMap' I.sum- , bench "mapChunks/mapChunks/convStream2" $ whnf fusedMap'2 I.sum- ]--main :: IO ()-main = do- print $ "fusedMap"- print $ fusedMap I.sum- print "fusedMap/filter"- print $ fusedMap3 I.sum- print "fusedMap4"- print $ fusedMap4 I.sum- print "fusedMap10"- print $ fusedMap10 I.sum-- defaultMain fusionBenches
− tests/fusion2.hs
@@ -1,234 +0,0 @@-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE RankNTypes #-}--module Main where--import Data.Iteratee as I-import Criterion.Main-import Control.Monad.Identity-import Control.Monad.Trans---runner- :: Enumeratee [Int] xs Identity a- -> [Int]- -> Iteratee xs Identity a- -> a-runner etee xs iter =- runIdentity $ enumPureNChunk xs 5 (joinI $ etee iter) >>= I.run---- test fusion of enumeratee/iteratee composition-runner2- :: Enumeratee [Int] xs Identity a- -> [Int]- -> Iteratee xs Identity a- -> a-runner2 etee xs iter =- runIdentity $ enumPureNChunk xs 5 (etee =$ iter) >>= I.run---- test fusion of enumerator/enumeratee composition-runner3- :: Enumeratee [Int] xs Identity a- -> [Int]- -> Iteratee xs Identity a- -> a-runner3 etee xs iter =- runIdentity $ (enumPureNChunk xs 5 $= etee) iter >>= I.run--m2 :: Enumeratee [Int] [Int] Identity a-m2 = mapChunks id ><> mapChunks (map (+1))--m3 :: Enumeratee [Int] [Int] Identity a-m3 = mapChunks id ><> mapChunks (map (+1)) ><> I.filter (even)--m4 :: Enumeratee [Int] [Int] Identity a-m4 = m2 ><> m2--m10 :: Enumeratee [Int] [Int] Identity a-m10 = m3 ><> m2 ><> m3 ><> m2--fusedMap :: Iteratee [Int] Identity a -> a-fusedMap = runner m2 [1..100]--fusedMap3 :: Iteratee [Int] Identity a -> a-fusedMap3 = runner m3 [1..100]--fusedMap4 :: Iteratee [Int] Identity a -> a-fusedMap4 = runner m4 [1..100]--fusedMap10 :: Iteratee [Int] Identity a -> a-fusedMap10 = runner m10 [1..100]---- experiment with using stream-fusion like constructs for--- enumeratees-data StreamF m b a = forall s. StreamF (s -> m (Step s b a)) !s--data Step s b a =- Done- | Yield [a] !s- | Next (b -> P2 [a] s)--data P2 a b = P2 !a !b--map_t :: Monad m => (a -> b) -> StreamF m a b-map_t fn = StreamF loop ()- where- loop () = return (Next (\a -> P2 [fn a] () ))-{-# INLINE map_t #-}--filter_t :: Monad m => (a -> Bool) -> StreamF m a a-filter_t pred = StreamF loop ()- where- loop () = return (Next (\a -> P2 (if pred a then [a] else []) ()) )-{-# INLINE filter_t #-}--cmp_t :: Monad m => StreamF m a b -> StreamF m b c -> StreamF m a c-cmp_t (StreamF fn1 s1_0) (StreamF fn2 s2_0) = StreamF loop (s1_0,s2_0,[])- where- loop (s1,s2,supply) = fn2 s2 >>= \r2 -> case r2 of- Done -> return Done- Yield cS s2' -> return $ Yield cS (s1,s2',supply)- Next fn -> case supply of- (b:bS) -> let P2 cS s2' = fn b- in return $ Yield cS (s1,s2',bS)- [] -> fn1 s1 >>= \r1 -> case r1 of- Done -> return Done- Yield aS s1' -> loop (s1', s2, aS)- Next f -> return $ Next $ \a ->- let P2 bS s1' = f a- in P2 [] (s1',s2,bS)-{-# INLINE cmp_t #-}--{--id_t :: Monad m => StreamF m a -> StreamF m a-id_t (StreamF istep s0) = StreamF loop s0- where- loop s = istep s >>= \r -> case r of- Done -> return Done- Yield a s' -> return $ Yield a s'- Skip s' -> return $ Skip s'-{-# INLINE id_t #-}--map_t :: Monad m => (a -> b) -> StreamF m a -> StreamF m b-map_t fn (StreamF istep s0) = StreamF loop s0- where- loop s = istep s >>= \r -> case r of- Done -> return Done- Yield a s' -> return $ Yield (fn a) s'- Skip s' -> return $ Skip s'-{-# INLINE map_t #-}--filter_t :: Monad m => (a -> Bool) -> StreamF m a -> StreamF m a-filter_t pred (StreamF istep s0) = StreamF loop s0- where- loop s = istep s >>= \r -> case r of- Done -> return Done- Yield a s' -> return $ if pred a then Yield a s' else Skip s'- Skip s' -> return $ Skip s'-{-# INLINE filter_t #-}--iStream :: Monad m => StreamF (Iteratee [a] m) a-iStream = StreamF loop []- where- loop (x:xs) = return $ Yield x xs- loop [] = do- r <- isStreamFinished- case r of- Nothing -> getChunk >>= loop- Just _ -> return Done-{-# INLINE iStream #-}---- this isn't really the correct type signature, but I don't know how to write--- what it actually is. Maybe it won't be a problem, with the correct type--- class constraints.-etee_t :: Monad m => (forall m. Monad m => StreamF m a -> StreamF m b) -> Enumeratee [a] [b] m x-etee_t stream_fn = case stream_fn iStream of- StreamF b_fn s0 -> unfoldConvStream fn s0- where- fn s = do- stepRes <- b_fn s- case stepRes of- Done -> return (s,[])- Yield a s' -> return (s',[a])- Skip s' -> return (s',[])-{-# INLINE etee_t #-}--type Trans m a b = Monad m => StreamF m a -> StreamF m b--}---etee_t :: Monad m => StreamF m a b -> Enumeratee [a] [b] m x-etee_t stream = case stream of- StreamF b_fn s0 -> unfoldConvStream fn (s0,[])- where- fn (s,[]) = do- ck <- getChunk- return ((s,ck),[])- fn (s,supply@(x:xs)) = do- stepRes <- lift $ b_fn s- case stepRes of- Done -> return ((s,supply),[])- Yield aS s' -> return ((s',supply),aS)- Next f -> let P2 bS s' = f x- in return ((s',xs),bS)--type Trans m a b = Monad m => StreamF m a b--m2_t :: Trans m Int Int-m2_t = map_t id `cmp_t` map_t (+1)--m3_t :: Trans m Int Int-m3_t = map_t id `cmp_t` map_t (+1) `cmp_t` filter_t even--m4_t :: Trans m Int Int-m4_t = m2_t `cmp_t` m2_t--fusedMap_t :: Iteratee [Int] Identity a -> a-fusedMap_t = runner_t m2_t [1..100]--fusedMap3_t :: Iteratee [Int] Identity a -> a-fusedMap3_t = runner_t m3_t [1..100]--fusedMap4_t :: Iteratee [Int] Identity a -> a-fusedMap4_t = runner_t m4_t [1..100]--runner_t- :: (forall m. Trans m Int x)- -> [Int]- -> Iteratee [x] Identity a- -> a-runner_t trans xs iter =- runIdentity $ enumPureNChunk xs 5 (joinI $ (etee_t trans) iter) >>= I.run--fusionBenches :: [Benchmark]-fusionBenches =- [ bench "mapChunks/mapChunks fusion" $ whnf fusedMap I.sum- , bench "mapChunks/filter fusion" $ whnf fusedMap3 I.sum- , bench "nested mapChunks/mapChunks fusion" $ whnf fusedMap4 I.sum- , bench "highly nested fusion" $ whnf fusedMap10 I.sum- , bench "stream mapChunks/mapChunks" $ whnf fusedMap_t I.sum- , bench "stream mapChunks/filter" $ whnf fusedMap3_t I.sum- , bench "stream nested mapChunks/mapChunks" $ whnf fusedMap4_t I.sum- ]--main :: IO ()-main = do- putStrLn "\n\n Original"- print $ "fusedMap"- print $ fusedMap I.sum- print "fusedMap/filter"- print $ fusedMap3 I.sum- print "fusedMap4"- print $ fusedMap4 I.sum- print "fusedMap10"- print $ fusedMap10 I.sum-- putStrLn "\n\n Stream-based"- print $ "fusedMap"- print $ fusedMap I.sum- print "fusedMap/filter"- print $ fusedMap3 I.sum- print "fusedMap4"- print $ fusedMap4 I.sum-- defaultMain fusionBenches