packages feed

conduit-algorithms 0.0.4.0 → 0.0.5.0

raw patch · 5 files changed

+66/−10 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Conduit.Algorithms.Utils: enumerateC :: Monad m => Conduit a m (Int, a)

Files

ChangeLog view
@@ -1,3 +1,7 @@+Version 0.0.5.0 2017-10-03 by luispedro+	* Add enumerateC conduit+	* Better mergeC conduit (list case)+ Version 0.0.4.0 2017-09-12 by luispedro 	* Fix bug in merge* conduits 
Data/Conduit/Algorithms.hs view
@@ -20,6 +20,7 @@ import qualified Data.Conduit as C import qualified Data.Conduit.Internal as CI import qualified Data.Set as S+import           Data.List (foldl') import           Control.Monad.Trans.Class (lift)  import           Data.Conduit.Algorithms.Utils (awaitJust)@@ -77,22 +78,42 @@ -- -- See 'mergeC2' mergeC :: (Ord a, Monad m) => [C.Source m a] -> C.Source m a-mergeC [] = return ()-mergeC [s] = s+mergeC [a] = a mergeC [a,b] = mergeC2 a b-mergeC args = mergeC2 (mergeC right) (mergeC left)-    where-        right = take n args-        left = drop n args-        n = (length args) `div` 2+mergeC cs = CI.ConduitM $ \rest -> let+        --go :: [CI.Pipe () i o () m ()] -> CI.Pipe () i o () m ()+        go [] = rest ()+        go st = do+            st' <- mapM norm1 st+            case gettop st' of+                Nothing -> rest ()+                Just (CI.HaveOutput c_next _ v, fs, next) ->+                    CI.HaveOutput (go (c_next:next)) (sequence_ fs) v+                _ -> error "This should be impossible (mergeC/go/case-gettop)"+        norm1 :: Monad m => CI.Pipe () i o () m () -> CI.Pipe () i o () m (CI.Pipe () i o () m ())+        norm1 c@CI.HaveOutput{} = return c+        norm1 c@CI.Done{} = return c+        norm1 (CI.PipeM p) = lift p >>= norm1+        norm1 (CI.NeedInput _ next) = norm1 (next ())+        norm1 (CI.Leftover next ()) = norm1 next+        gettop = foldl' collect Nothing+        collect cur CI.Done{} = cur+        collect Nothing c@(CI.HaveOutput _ f _) = Just (c, [f], [])+        collect (Just (best_c@(CI.HaveOutput _ _ best_v), fs, next)) c@(CI.HaveOutput _ f v)+            | v >= best_v = Just (best_c, f:fs, c:next)+            | otherwise = Just (c, f:fs, best_c:next)+        collect _ _ = error "This situation should be impossible (mergeC/collect)" +    in go (map (($ CI.Done) . CI.unConduitM) cs)++ -- | Take two sorted sources and merge them. -- -- See 'mergeC' mergeC2 :: (Ord a, Monad m) => C.Source m a -> C.Source m a -> C.Source m a mergeC2 (CI.ConduitM s1) (CI.ConduitM s2) = CI.ConduitM $ \rest -> let         go right@(CI.HaveOutput s1' f1 v1) left@(CI.HaveOutput s2' f2 v2)-            | compare v1 v2 /= GT = CI.HaveOutput (go s1' left) (f1 >> f2) v1+            | v1 <= v2 = CI.HaveOutput (go s1' left) (f1 >> f2) v1             | otherwise = CI.HaveOutput (go right s2') (f1 >> f2) v2         go right@CI.Done{} (CI.HaveOutput s f v) = CI.HaveOutput (go right s) f v         go (CI.HaveOutput s f v) left@CI.Done{}  = CI.HaveOutput (go s left)  f v@@ -108,4 +129,3 @@         go (CI.Leftover next ()) left = go next left         go right (CI.Leftover next ()) = go right next     in go (s1 CI.Done) (s2 CI.Done)-
Data/Conduit/Algorithms/Tests.hs view
@@ -17,6 +17,7 @@ import           Data.Conduit ((.|)) import           Data.List (sort) import           System.Directory (removeFile)+import           Control.Monad (forM_)  import qualified Data.Conduit.Algorithms as CAlg import qualified Data.Conduit.Algorithms.Utils as CAlg@@ -45,13 +46,32 @@                                 [ CC.yieldMany i1                                 , CC.yieldMany i2                                 , CC.yieldMany i3+                                , CC.yieldMany i3                                 ]     where+        expected = sort (concat [i1, i2, i3, i3])+        i1 = [ 1, 2, 4 :: Int]+        i2 = [ 1, 4, 4, 5]+        i3 = [-1, 0, 7]++case_mergeCmonad = shouldProduce expected $+                            CAlg.mergeC+                                [ mYield i1+                                , mYield i2+                                , mYield i3+                                ]+    where         expected = sort (concat [i1, i2, i3])+        mYield lst = do+            let lst' = map return lst+            forM_ lst' $ \elem -> do+                elem' <- elem+                C.yield elem'         i1 = [ 0, 2, 4 :: Int]         i2 = [ 1, 3, 4, 5]         i3 = [-1, 0, 7] + case_mergeC2 = shouldProduce [0, 1, 1, 2, 3, 5 :: Int] $                             CAlg.mergeC2                                 (CC.yieldMany [0, 1, 2])@@ -71,6 +91,9 @@  case_groupC = shouldProduce [[0,1,2], [3,4,5], [6,7,8], [9, 10 :: Int]] $                             CC.yieldMany [0..10] .| CAlg.groupC 3++case_enumerateC = shouldProduce [(0,'z'), (1,'o'), (2,'t')] $+                            CC.yieldMany ("zot" :: [Char]) .| CAlg.enumerateC  case_removeRepeatsC = shouldProduce [0,1,2,3,4,5,6,7,8,9, 10 :: Int] $                             CC.yieldMany [0,0,0,1,1,1,2,2,3,4,5,6,6,6,6,7,7,8,9,10,10] .| CAlg.removeRepeatsC
Data/Conduit/Algorithms/Utils.hs view
@@ -8,6 +8,7 @@ -} module Data.Conduit.Algorithms.Utils     ( awaitJust+    , enumerateC     , groupC     ) where @@ -29,6 +30,14 @@ -- http://neilmitchell.blogspot.de/2015/07/thoughts-on-conduits.html awaitJust :: Monad m => (a -> C.Conduit a m b) -> C.Conduit a m b awaitJust f = C.await >>= maybe (return ()) f++-- Conduit analogue to Python's enumerate function+enumerateC :: Monad m => C.Conduit a m (Int, a)+enumerateC = enumerateC' 0+    where+        enumerateC' !i = awaitJust $ \v -> do+                                        C.yield (i, v)+                                        enumerateC' (i + 1)  -- | groupC yields the input as groups of 'n' elements. If the input is not a -- multiple of 'n', the last element will be incomplete
conduit-algorithms.cabal view
@@ -1,5 +1,5 @@ name:               conduit-algorithms-version:            0.0.4.0+version:            0.0.5.0 synopsis:           Conduit-based algorithms description:        Algorithms on Conduits, including higher level asynchronous                     processing and some other utilities.