packages feed

pipes 4.0.1 → 4.0.2

raw patch · 5 files changed

+113/−30 lines, 5 filesdep ~criterion

Dependency ranges changed: criterion

Files

pipes.cabal view
@@ -1,5 +1,5 @@ Name: pipes-Version: 4.0.1+Version: 4.0.2 Cabal-Version: >= 1.10 Build-Type: Simple License: BSD3@@ -77,7 +77,7 @@      Build-Depends:         base      >= 4       && < 5  ,-        criterion >= 0.8     && < 0.9,+        criterion >= 0.6.2.1 && < 0.9,         mtl       >= 2.0.1.0 && < 2.2,         pipes     >= 4.0.0   && < 4.1 @@ -106,7 +106,7 @@      Build-Depends:         base         >= 4       && < 5  ,-        criterion    >= 0.8     && < 0.9,+        criterion    >= 0.6.2.1 && < 0.9,         deepseq                         ,         mtl          >= 2.0.1.0 && < 2.2,         pipes        >= 4.0.0   && < 4.1,
src/Pipes.hs view
@@ -71,11 +71,11 @@  import Control.Applicative (Applicative(pure, (<*>)), Alternative(empty, (<|>))) import Control.Monad (MonadPlus(mzero, mplus))-import Control.Monad.IO.Class (MonadIO(liftIO)) -- transformers-import Control.Monad.Trans.Class (MonadTrans(lift)) --transformers+import Control.Monad.IO.Class (MonadIO(liftIO))+import Control.Monad.Trans.Class (MonadTrans(lift)) import Control.Monad.Trans.Error (ErrorT(runErrorT))-import Control.Monad.Trans.Identity (IdentityT(runIdentityT)) --transformers-import Control.Monad.Trans.Maybe (MaybeT(runMaybeT)) --transformers+import Control.Monad.Trans.Identity (IdentityT(runIdentityT))+import Control.Monad.Trans.Maybe (MaybeT(runMaybeT)) import Data.Foldable (Foldable) import qualified Data.Foldable as F import Data.Monoid (Monoid(..))@@ -470,10 +470,17 @@ {-# INLINABLE next #-}  -- | Convert a 'F.Foldable' to a 'Producer'-each :: (Monad m, F.Foldable f) => f a -> Producer' a m ()-each = F.mapM_ yield+each :: (Monad m, Foldable f) => f a -> Producer' a m ()+each = F.foldr (\a p -> yield a >> p) (return ()) {-# INLINABLE each #-}+{-  The above code is the same as: +> each = Data.Foldable.mapM_ yield++    ... except writing it directly in terms of `Data.Foldable.foldr` improves+    build/foldr fusion+-}+ -- | Convert an 'Enumerable' to a 'Producer' every :: (Monad m, Enumerable t) => t m a -> Producer' a m () every it = discard >\\ enumerate (toListT it)@@ -506,5 +513,5 @@ #endif     "Data.Foldable" re-exports 'Foldable' (the class name only) -    "Data.Void" re-exports 'Void'.+    "Data.Void" re-exports 'Void' -}
src/Pipes/Core.hs view
@@ -81,9 +81,13 @@     , (<\\)     , (//<)     , (<<+)++    -- * Re-exports+    , module Data.Void     ) where -import Data.Void (Void, absurd)+import Data.Void (Void)+import qualified Data.Void as V import Pipes.Internal (Proxy(..))  {- $proxy@@ -121,8 +125,8 @@ runEffect = go   where     go p = case p of-        Request v _ -> absurd v-        Respond v _ -> absurd v+        Request v _ -> V.absurd v+        Respond v _ -> V.absurd v         M       m   -> m >>= go         Pure    r   -> return r {-# INLINABLE runEffect #-}@@ -842,3 +846,7 @@   ; "f >\\ request x" forall f x . f >\\ request x = f x    #-}++{- $reexports+    @Data.Void@ re-exports the 'Void' type+-}
src/Pipes/Prelude.hs view
@@ -11,8 +11,9 @@     dependency on the @text@ package.      Also, 'stdinLn' and 'stdoutLn' remove and add newlines, respectively.  This-    behavior is intended to simplify examples.  The upcoming 'ByteString' and-    'Text' utilities for @pipes@ will preserve newlines.+    behavior is intended to simplify examples.  The corresponding @stdin@ and+    @stdout@ utilities from @pipes-bytestring@ and @pipes-text@ preserve+    newlines. -}  {-# LANGUAGE RankNTypes, CPP #-}@@ -98,14 +99,14 @@ import Foreign.C.Error (Errno(Errno), ePIPE) import qualified GHC.IO.Exception as G import Pipes+import Pipes.Core import Pipes.Internal import qualified System.IO as IO-import qualified Prelude #ifndef haskell98 import Control.Monad.Trans.State.Strict (get, put)-import Pipes.Core import Pipes.Lift (evalStateP) #endif+import qualified Prelude import Prelude hiding (       all     , and@@ -548,9 +549,9 @@ head :: (Monad m) => Producer a m () -> m (Maybe a) head p = do     x <- next p-    case x of-        Left   _     -> return Nothing-        Right (a, _) -> return (Just a)+    return $ case x of+        Left   _     -> Nothing+        Right (a, _) -> Just a {-# INLINABLE head #-}  -- | Index into a 'Producer'
src/Pipes/Tutorial.hs view
@@ -80,6 +80,9 @@      -- * Appendix: Types     -- $types++    -- * Appendix: Time Complexity+    -- $timecomplexity     ) where  import Control.Category@@ -1358,27 +1361,46 @@      However, polymorphic type synonyms cause problems in many other cases: -    * They induce higher-rank types and require you to enable the @RankNTypes@-      extension to use them in your own type signatures.--    * They give the wrong behavior when used in the negative position of a-      function like this:+    * They usually give the wrong behavior when used as the argument of a+      function (known as the \"negative\" or \"contravariant\" position) like+      this:  > f :: Producer' a m r -> ...  -- Wrong > > f :: Producer  a m r -> ...  -- Right -    * You can't use them within other types without the @ImpredicativeTypes@-      extension:+      The former function only accepts polymorphic 'Producer's as arguments.+      The latter function accepts both polymorphic and concrete 'Producer's,+      which is probably what you want. -> io :: IO (Producer' a m r)  -- Type error+    * Even when you desire a polymorphic argument, this induces a higher-ranked+      type, because it translates to a @forall@ which you cannot factor out to+      the top-level to simplify the type signature: -    * You can't partially apply them:+> f :: (forall x' x y' . Proxy x' x y' m r) -> ... +      These kinds of type signatures require the @RankNTypes@ extension.++    * Even when you have polymorphic type synonyms as the result of a function+      (i.e.  the \"positive\" or \"covariant\" position), recent versions of+      @ghc@ such still require the @RankNTypes@ extension.  For example, the+      'Pipes.Prelude.fromHandle' function from "Pipes.Prelude" requires+      @RankNTypes@ to compile correctly on @ghc-7.6.3@:++> fromHandle :: (MonadIO m) => Handle -> Producer' String m ()++    * You can't use polymorphic type synonyms inside other type constructors+      without the @ImpredicativeTypes@ extension:++> io :: IO (Producer' a m r)  -- Type error without ImpredicativeTypes++    * You can't partially apply polymorphic type synonyms:+ > stack :: MaybeT (Producer' a m) r  -- Type error      In these scenarios you should fall back on the concrete type synonyms, which-    are better behaved.+    are better behaved.  If concrete type synonyms are unsatisfactory, then ask+    @ghc@ to infer the most general type signature and use that.      For the purposes of debugging type errors you can just remember that: @@ -1438,4 +1460,49 @@ > type Server'       b' b m r = forall x' x      . Proxy x' x b' b m r > type Client'  a' a      m r = forall      y' y . Proxy a' a y' y m r +-}++{- $timecomplexity+    There are three functions that give quadratic time complexity when used in+    within @pipes@:++    * 'sequence'++    * 'replicateM'++    * 'mapM'++    For example, the time complexity of this code segment scales quadratically+    with `n`:++> import Control.Monad (replicateM)+> import Pipes+>+> quadratic :: Int -> Consumer a m [a]+> quadratic n = replicateM n await++    These three functions are generally bad practice to use, because all three+    of them correspond to \"ListT done wrong\", building a list in memory+    instead of streaming results.++    However, sometimes situations arise where one deliberately intends to build+    a list in memory.  The solution is to use the \"codensity transformation\"+    to transform the code to run with linear time complexity.  This involves:++    * wrapping the code in the @Codensity@ monad transformer (from+      @Control.Monad.Codensity@ module of the @kan-extensions@ package) using+      'lift'++    * applying 'sequence' \/ 'replicateM' \/ 'mapM'++    * unwrapping the code using @lowerCodensity@++    To illustrate this, we'd transform the above example to:++> import Control.Monad.Codensity (lowerCodensity)+> +> linear :: (Monad m) => Int -> Consumer a m [a]+> linear n = lowerCodensity $ replicateM n $ lift await++    This will produce the exact same result, but in linear time. -}