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 +3/−3
- src/Control/Quiver/Interleave.hs +18/−7
- test/PropTests.hs +0/−45
- test/Spec.hs +51/−0
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