quiver-interleave (empty) → 0.1.0.0
raw patch · 7 files changed
+209/−0 lines, 7 filesdep +QuickCheckdep +basedep +hspecsetup-changed
Dependencies added: QuickCheck, base, hspec, quiver, quiver-interleave
Files
- LICENSE +20/−0
- README.md +9/−0
- Setup.hs +2/−0
- quiver-interleave.cabal +47/−0
- src/Control/Quiver/Interleave.hs +50/−0
- stack.yaml +36/−0
- test/PropTests.hs +45/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2016 Ivan Lazar Miljenovic++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,9 @@+quiver-interleave+=================++[](https://hackage.haskell.org/package/quiver-interleave) [](https://travis-ci.org/ivan-m/quiver-interleave)++Interleave values from multiple [Quivers], merging them using a+provided comparison function.++[Quivers]: http://hackage.haskell.org/package/quiver
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ quiver-interleave.cabal view
@@ -0,0 +1,47 @@+name: quiver-interleave+version: 0.1.0.0+synopsis: Interleave values from multiple Quivers+description: Combine multiple Quivers into one.+license: MIT+license-file: LICENSE+author: Ivan Lazar Miljenovic+maintainer: Ivan.Miljenovic@gmail.com+-- copyright:+category: Control+build-type: Simple+extra-source-files: README.md+ , stack.yaml+cabal-version: >=1.10++tested-with: GHC == 7.10.2, GHC == 7.11.*++source-repository head+ type: git+ location: https://github.com/ivan-m/quiver-interleave.git+++library+ exposed-modules: Control.Quiver.Interleave+ -- other-modules:+ build-depends: base >=4.8 && <4.9+ , quiver >= 1.1.3 && < 1.2+ hs-source-dirs: src+ default-language: Haskell2010++ ghc-options: -Wall++test-suite properties+ type: exitcode-stdio-1.0+ main-is: PropTests.hs+ build-depends: quiver-interleave+ , base+ , quiver++ , QuickCheck >= 2.5 && < 2.9+ -- Just to make it nicer to write+ , hspec >= 2.1 && < 2.3+ hs-source-dirs: test+ default-language: Haskell2010++ ghc-options: -Wall+ ghc-prof-options: -prof -auto
+ src/Control/Quiver/Interleave.hs view
@@ -0,0 +1,50 @@+{- |+ Module : Control.Quiver.Interleave+ Description : Interleave values from multiple Quivers+ Copyright : (c) Ivan Lazar Miljenovic+ License : MIT+ Maintainer : Ivan.Miljenovic@gmail.com++++ -}+module Control.Quiver.Interleave+ ( spinterleave+ ) where++import Control.Quiver+import Control.Quiver.Internal (P (..))++import Data.Either (rights)+import Data.Function (on)+import Data.List (sortBy)++--------------------------------------------------------------------------------++-- | Interleave the elements of the provided producers such that the+-- result consists of the values from all of them merged in by the+-- provided comparison function.+--+-- 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 ()+spinterleave cmp ps = do+ aps <- qlift (rights <$> mapM spnext ps)+ go aps+ where+ go [] = return ()+ go aps = do let (a,p):aps' = sortBy (cmp`on`fst) aps+ emit_ a+ eap' <- qlift $ spnext p+ go (either (const aps') (:aps') eap')++-- 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))+spnext = go+ where+ go p = case p of+ Consume _ _ p' -> go p'+ Produce b pr _ -> return (Right (b, pr ()))+ Enclose f -> f >>= go+ Deliver r -> return (Left r)
+ stack.yaml view
@@ -0,0 +1,36 @@+# This file was automatically generated by stack init+# For more information, see: http://docs.haskellstack.org/en/stable/yaml_configuration/++# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)+resolver: lts-5.11++# Local packages, usually specified by relative directory name+packages:+- '.'+# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)+extra-deps:+- quiver-1.1.3++# Override default flag values for local packages and extra-deps+flags: {}++# Extra package databases containing global packages+extra-package-dbs: []++# Control whether we use the GHC we find on the path+# system-ghc: true++# Require a specific version of stack, using version ranges+# require-stack-version: -any # Default+# require-stack-version: >= 1.0.0++# Override the architecture used by stack, especially useful on Windows+# arch: i386+# arch: x86_64++# Extra directories used by stack for building+# extra-include-dirs: [/path/to/dir]+# extra-lib-dirs: [/path/to/dir]++# Allow a newer minor version of GHC than the snapshot specifies+# compiler-check: newer-minor
+ test/PropTests.hs view
@@ -0,0 +1,45 @@+{-# 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