packages feed

quiver-interleave 0.1.0.0 → 0.2.0.0

raw patch · 4 files changed

+72/−55 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Control.Quiver.Interleave: spinterleave :: (Monad f) => (b -> b -> Ordering) -> [P a a' b () f e] -> P a a' b () f ()
+ Control.Quiver.Interleave: spinterleave :: (Monad f) => (b -> b -> Ordering) -> [P a a' b () f (SPResult e)] -> P a a' b () f (SPResult e)

Files

quiver-interleave.cabal view
@@ -1,5 +1,5 @@ name:                quiver-interleave-version:             0.1.0.0+version:             0.2.0.0 synopsis:            Interleave values from multiple Quivers description:         Combine multiple Quivers into one. license:             MIT@@ -30,9 +30,9 @@    ghc-options:         -Wall -test-suite properties+test-suite interleave-tests   type:                exitcode-stdio-1.0-  main-is:             PropTests.hs+  main-is:             Spec.hs   build-depends:       quiver-interleave                      , base                      , quiver
src/Control/Quiver/Interleave.hs view
@@ -12,10 +12,11 @@   ( spinterleave   ) where -import Control.Quiver import Control.Quiver.Internal (P (..))+import Control.Quiver.SP -import Data.Either   (rights)+import Data.Bool     (bool)+import Data.Either   (partitionEithers) import Data.Function (on) import Data.List     (sortBy) @@ -28,16 +29,26 @@ -- That is, if each provided Quiver returns a sequence of ordered -- elements, then this would be the same as obtaining all the elements -- and sorting them.-spinterleave :: (Monad f) => (b -> b -> Ordering) -> [P a a' b () f e] -> P a a' b () f ()+--+-- If any provided Quiver results in anything except 'SPComplete' then+-- entire stream halts, propagating the error.+spinterleave :: (Monad f) => (b -> b -> Ordering) -> [P a a' b () f (SPResult e)] -> P a a' b () f (SPResult e) spinterleave cmp ps = do-  aps <- qlift (rights <$> mapM spnext ps)-  go aps+  (errs, aps) <- qlift (partitionEithers <$> mapM spnext ps)+  case filter isErr errs of+    (e:_) -> deliver e+    _     -> go aps   where-    go []  = return ()+    go []  = spcomplete     go aps = do let (a,p):aps' = sortBy (cmp`on`fst) aps                 emit_ a                 eap' <- qlift $ spnext p-                go (either (const aps') (:aps') eap')+                either (\e -> bool (go aps') (deliver e) (isErr e))+                       (go . (:aps'))+                       eap'++    isErr SPComplete = False+    isErr _          = True  -- TODO: consider having it just return a Maybe spnext :: (Monad f) => P a a' b () f r -> f (Either r (b, P a a' b () f r))
− test/PropTests.hs
@@ -1,45 +0,0 @@-{-# LANGUAGE RankNTypes #-}-{- |-   Module      : Main-   Description : Property tests-   Copyright   : (c) Ivan Lazar Miljenovic-   License     : MIT-   Maintainer  : Ivan.Miljenovic@gmail.com---- -}-module Main (main) where--import Control.Quiver.Interleave--import Control.Quiver.SP-import Data.Functor.Identity-import Data.List             (sort)--import Test.Hspec-import Test.Hspec.QuickCheck (prop)-import Test.QuickCheck------------------------------------------------------------------------------------main :: IO ()-main = hspec $-  describe "interleave" $-    prop "same as list-based" $-      forAllShrink orderedSubLists shrink $ \ass ->-        interleaveSort ass == sort (concat ass)--spToList :: SQ a x f [a]-spToList = spfoldr (:) []--spIdentity :: SQ a b Identity c -> c-spIdentity = runIdentity . sprun---- Assumes each sub-list is ordered.-interleaveSort :: (Ord a) => [[a]] -> [a]-interleaveSort ass = spIdentity (spinterleave compare (map spevery ass) >->> spToList >&> snd)---- Each sub-list is ordered-orderedSubLists :: Gen [[Int]]-orderedSubLists = listOf orderedList
+ test/Spec.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE RankNTypes #-}+{- |+   Module      : Main+   Description : Property tests+   Copyright   : (c) Ivan Lazar Miljenovic+   License     : MIT+   Maintainer  : Ivan.Miljenovic@gmail.com++++ -}+module Main (main) where++import Control.Quiver.Interleave++import Control.Quiver.SP+import Data.Functor.Identity+import Data.List             (sort)++import Test.Hspec+import Test.Hspec.QuickCheck (prop)+import Test.QuickCheck++--------------------------------------------------------------------------------++main :: IO ()+main = hspec $+  describe "interleave" $ do+    prop "same as list-based" $+      forAllShrink orderedSubLists shrink $ \ass ->+        interleaveSort ass == sort (concat ass)+    it "propagates errors" $+      spIdentity (spinterleave compare [spevery [1,4,7]+                                       ,spevery [2,5,8]+                                       ,3 >:> spfailed "failed"]+                  >->> spToList)+        == (SPFailed "failed", [1,2,3] :: [Int]) -- The error and the values found before the error came up.++spToList :: SQ a x f [a]+spToList = spfoldr (:) []++spIdentity :: SQ a b Identity c -> c+spIdentity = runIdentity . sprun++-- Assumes each sub-list is ordered.+interleaveSort :: (Ord a) => [[a]] -> [a]+interleaveSort ass = spIdentity (spinterleave compare (map spevery ass) >->> spToList >&> snd)++-- Each sub-list is ordered+orderedSubLists :: Gen [[Int]]+orderedSubLists = listOf orderedList