packages feed

streaming 0.1.0.16 → 0.1.0.17

raw patch · 2 files changed

+107/−8 lines, 2 files

Files

Streaming/Prelude.hs view
@@ -17,6 +17,19 @@ > import qualified Pipes.Prelude as P > import qualified System.IO as IO +     Here are some correspondences between the types employed here and elsewhere:++>               streaming             |            pipes               |       conduit      |  io-streams+> ----------------------------------------------------------------------------------------------------------+> Stream (Of a) m ()                  | Producer a m ()                | Source m a         | InputStream a+>                                     | ListT m a                      | ConduitM () o m () | Generator r ()+> ----------------------------------------------------------------------------------------------------------+> Stream (Of a) m r                   | Producer a m r                 | ConduitM () o m r  | Generator a r+> ----------------------------------------------------------------------------------------------------------+> Stream (Of a) m (Stream (Of a) m r) | Producer a m (Producer a m r)  | +> -----------------------------------------------------------------------------------------------------------+> Stream (Stream (Of a) m) r          | FreeT (Producer a m) m r       |+ -} {-# LANGUAGE RankNTypes, BangPatterns, DeriveDataTypeable,              DeriveFoldable, DeriveFunctor, DeriveTraversable #-}@@ -200,7 +213,30 @@   m :> x >>= f = let m' :> y = f x in mappend m m' :> y   {-#INLINE (>>=) #-} +{-| Note that 'lazily', 'strictly', 'fst'', and 'mapOf' are all so-called /natural transformations/ on the primitive @Of a@ functor+    If we write +  +>  type f ~> g = forall x . f x -> g x+  +   then we have+  +>  mapOf  :: (a -> b) -> Of a ~> Of b+>  lazily :: Of a -> (,) a+>  fst'   :: Of a -> Identity a +   Manipulation of a @Stream f m r@ by mapping often turns on recognizing natural transformations of @f@,+   thus++>  S.map :: (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r+>  S.map f = maps (mapOf f)+  +  This rests on recognizing that @mapOf@ is a natural transformation; note though+  that it results in such a transformation as well:+  +>  S.map :: (a -> b) -> Stream (Of a) m ~> Stream (Of b) m   +  ++-} lazily :: Of a b -> (a,b) lazily = \(a:>b) -> (a,b) {-# INLINE lazily #-}@@ -215,7 +251,8 @@ snd' :: Of a b -> b snd' (a :> b) = b -+mapOf :: (a -> b) -> Of a r -> Of b r+mapOf f (a:> b) = (f a :> b) {-| Break a sequence when a element falls under a predicate, keeping the rest of     the stream as the return value. @@ -1178,10 +1215,11 @@ >>> S.sum $ do {yield 1; yield 2} 3 ->>> S.sum $ do {yield 1;  lift $ putStrLn "# 1 was yielded";  yield 2;  lift $ putStrLn "# 2 was yielded"}-# 1 was yielded-# 2 was yielded+>>> S.sum $ do {yield 1; lift $ putStrLn "/* 1 was yielded */"; yield 2; lift $ putStrLn "/* 2 was yielded */"}+/* 1 was yielded */+/* 2 was yielded */ 3+  >>> let prompt :: IO Int; prompt = putStrLn "Enter a number:" >> readLn  >>> S.sum $ do {lift prompt >>= yield ; lift prompt >>= yield ; lift prompt >>= yield}
streaming.cabal view
@@ -1,10 +1,12 @@ name:                streaming-version:             0.1.0.16+version:             0.1.0.17 cabal-version:       >=1.10 build-type:          Simple synopsis:            a free monad transformer optimized for streaming applications -description:         @Stream@ can be used wherever +description:         __The free stream on a streamable functor__+                     .+                     @Stream@ can be used wherever                       <https://hackage.haskell.org/package/free-4.12.1/docs/Control-Monad-Trans-Free.html FreeT>                       is used. The compiler's                      standard range of optimizations work better for operations @@ -42,6 +44,57 @@                      Somehow, we didn't even need a four-character operator for that, nor advice                      about best practices! - just ordinary Haskell common sense.                       .+                     __Didn't I hear that free monads are horrible?__+                     .+                     If @Stream f m r@ is instantiated to @Stream f Identity m r@ then we have+                     the standard /free monad construction/. This is subject to certain familiar+                     objections from an efficiency perspective; efforts have been made to+                     substitute exotic cps-ed implementations and so forth. +                     .+                     In fact, the standard fast talk about /retraversing binds/ and /quadratic explosions/ and+                     /costly appends/, and so on become transparent nonsense with @Stream f m r@  +                     in its streaming use. The insight needed to see this is basically nil: Where @m@ is read as+                     @IO@, or some transformed @IO@, then the dreaded /retraversing of the binds/ +                     in a stream expression would involve repeating all the past actions. Don't worry, to get e.g. the+                     second chunk of bytes from a handle, you won't need to start over and get the first+                     one again! The first chunk has vanished into an unrepeatable past.+                     .+                     All of the difficulties a streaming library is attempting to avoid+                     are concentrated in the deep irrationality of+                     .+                     > sequence :: (Monad m, Traversable t) => t (m a) -> m (t a)+                     .+                     In the streaming context, this becomes +                     .+                     > sequence :: Monad m, Functor f => Stream f m r -> Stream f m r+                     > sequence = id+                     .+                     It is of course easy enough to define+                     .+                     > accumulate :: Monad m, Functor f => Stream f m r -> m (Stream f Identity r)+                     .+                     or @reifyBinds@, as you might call it. Small experience will+                     teach the user how to avoid or control the sort of accumulation +                     characteristic of @sequence@ in its various guises e.g. @mapM f = sequence . map f@ and +                     @traverse f = sequence . fmap f@ and  @replicateM n = sequence . replicate n@. +                     See for example the types of +                     .+                     > Control.Monad.replicateM :: Int -> m a -> m [a]+                     > Streaming.Prelude.replicateM :: Int -> m a -> Stream (Of a) m ()+                     .+                     If you want to tempt fate and replicate the irrationality of @Control.Monad.replicateM@, +                     then sure, you can write the hermaphroditic, chimerical+                     .+                     > accumulate . Streaming.Prelude.replicateM :: Int -> m a -> m (Stream (Of a) Identity ())+                     .+                     but once you know how to operate with a stream directly you will see less and less point+                     in what is called /extracting the (structured) value from IO/. With @sequence@ and @traverse@,+                     we accumulate a structure holding pure values from a structure holding monadic +                     values. Why bother when you have intrinsically monadic structures? @Stream f m r@ +                     gives you an immense body of such structures and a simple discipline for working with them.+                     .+                     __Interoperation with the streaming-io libraries__+                     .                      The simplest form of interoperation with                       <http://hackage.haskell.org/package/pipes pipes>                      is accomplished with this isomorphism:@@ -70,6 +123,8 @@                      > Free.iterTM  Stream.wrap              :: FreeT f m a -> Stream f m a                      > Stream.iterTM Free.wrap               :: Stream f m a -> FreeT f m a                       .+                     __Examples__+                     .                      For some simple ghci examples, see the commentary throughout the Prelude module.                      For slightly more advanced usage see the commentary in the haddocks of <https://hackage.haskell.org/package/streaming-bytestring streaming-bytestring>                      and e.g. @@ -77,6 +132,12 @@                      the io-streams tutorial.                      Here's a simple <https://gist.github.com/michaelt/2dcea1ba32562c091357 streaming GET request> with                      intrinsically streaming byte streams.+                     .+                     __Problems__+                     .+                     Questions about this library can be put as issues through the github site or+                     on the <https://groups.google.com/forum/#!forum/haskell-pipes pipes mailing list>. +                     (This library understands itself as part of the pipes "ecosystem.")                                             license:             BSD3@@ -86,7 +147,7 @@ stability:           Experimental homepage:            https://github.com/michaelt/streaming bug-reports:         https://github.com/michaelt/streaming/issues-category:            Data, Pipes+category:            Data, Pipes, Streaming source-repository head     type: git     location: https://github.com/michaelt/streaming@@ -107,7 +168,7 @@   build-depends:       base >=4.6 && <5                      , mtl >=2.1 && <2.3                      , mmorph >=1.0 && <1.2-                     , transformers >=0.3 && <0.5+                     , transformers >=0.4 && <0.5    default-language:  Haskell2010