-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | an elementary streaming prelude and general stream type. -- -- This package contains two modules, Streaming and -- Streaming.Prelude. The principal module, -- Streaming.Prelude, exports an elementary streaming prelude -- focused on a simple "source" or "producer" type, namely Stream (Of -- a) m r. This is a sort of effectful version of ([a],r) -- in which successive elements of type a arise from some sort -- of monadic action before the succession ends with a value of type -- r. Everything in the library is organized to make programming -- with this type as simple as possible, by the simple expedient of -- making it as close to Prelude and Data.List as -- possible. Thus for example the trivial program -- --
-- >>> S.sum $ S.take 3 (S.readLn :: Stream (Of Int) IO ()) -- 1<Enter> -- 2<Enter> -- 3<Enter> -- 6 :> () ---- -- sums the first three valid integers from user input. Similarly, -- --
-- >>> S.stdoutLn $ S.map (map toUpper) $ S.take 2 S.stdinLn -- hello<Enter> -- HELLO -- world!<Enter> -- WORLD! ---- -- upper-cases the first two lines from stdin as they arise, and sends -- them to stdout. And so on, with filtering, mapping, breaking, -- chunking, zipping, unzipping, replicating and so forth: we program -- with streams of Ints or Strings directly as if they -- constituted something like a list. That's because streams really do -- constitute something like a list, and the associated operations can -- mostly have the same names. (A few, like reverse, don't -- stream and thus disappear; others like unzip are here given -- properly streaming formulation for the first time.) And we everywhere -- oppose "extracting a pure list from IO", which is the origin of -- typical Haskell memory catastrophes. Basically any case where you are -- tempted to use mapM, replicateM, traverse -- or sequence with Haskell lists, you would do better to use -- something like Stream (Of a) m r. The type signatures are a -- little fancier, but the programs themselves are mostly the same. In -- fact, they are mostly simpler. Thus, consider the trivial demo -- program mentioned in this SO question -- --
-- main = mapM newIORef [1..10^8::Int] >>= mapM readIORef >>= mapM_ print ---- -- The new user notices that this exhausts memory, and worries about the -- efficiency of Haskell IORefs. But of course it exhausts -- memory! Look what it says! The problem is immediately cured by writing -- --
-- main = S.print $ S.mapM readIORef $ S.mapM newIORef $ S.each [1..10^8::Int] ---- -- which really does what the other program was meant to do, uses no more -- memory than hello-world, and is simpler anyway, since -- it doesn't involve the detour of "extracting a list from IO". Almost -- every use of list mapM, replicateM, -- traverse and sequence produces this problem on a -- smaller scale. People get used to it, as if it were characteristic of -- Haskell programs to use a lot of memory. But in truth "extracting a -- list or sequence from IO" is mostly just bad practice pure and simple. -- Of course, mapM, replicateM, traverse and -- sequence make sense for lists, under certain conditions! But -- unsafePerformIO also makes sense under certain conditions. -- -- The Streaming module exports the general type, Stream f m -- r, which can be used to stream successive distinct steps -- characterized by any functor f, though we are mostly -- interested in organizing computations of the form Stream (Of a) m -- r. The streaming-IO libraries have various devices for dealing -- with effectful variants of [a] or ([a],r) in which -- the emergence of successive elements somehow depends on IO. But it is -- only with the general type Stream f m r, or some equivalent, -- that one can envisage (for example) the connected streaming of their -- sorts of stream - as one makes lists of lists in the Haskell -- Prelude and Data.List. One needs some such type if -- we are to express properly streaming equivalents of e.g. -- --
-- group :: Ord a => [a] -> [[a]] -- chunksOf :: Int -> [a] -> [[a]] -- lines :: [Char] -> [[Char]] -- but similarly with byte streams, etc. ---- -- to mention a few obviously desirable operations. (This is explained -- more elaborately in the readme below.) -- -- One could of course throw something like the present Stream -- type on top of a prior stream concept: this is how pipes and -- pipes-group (which are very much our model here) use -- FreeT. But once one grasps the iterable stream concept needed -- to express those functions then one will also see that, with it, one -- is already in possession of a complete elementary streaming -- library - since one possesses Stream ((,) a) m r or -- equivalently Stream (Of a) m r. This is the type of a -- 'generator' or 'producer' or 'source' or whatever you call an -- effectful stream of items. The present Streaming.Prelude is thus -- the simplest streaming library that can replicate anything like the -- API of the Prelude and Data.List. -- -- The emphasis of the library is on interoperation; for the rest its -- advantages are: extreme simplicity, re-use of intuitions the user has -- gathered from mastery of Prelude and Data.List, and -- a total and systematic rejection of type synonyms. The two conceptual -- pre-requisites are some comprehension of monad transformers and some -- familiarity with 'rank 2 types'. It is hoped that experimentation with -- this simple material, starting with the ghci examples in -- Streaming.Prelude, will give people who are new to these -- concepts some intuition about their importance. The most fundamental -- purpose of the library is to express elementary streaming ideas -- without reliance on a complex framework, but in a way that integrates -- transparently with the rest of Haskell, using ideas - e.g. rank 2 -- types, which are here implicit or explicit in most mapping - that the -- user can carry elsewhere, rather than chaining her understanding to -- the curiosities of a so-called streaming IO framework (as necessary as -- that is for certain purposes.) -- -- See the readme below for further explanation, including the -- examples linked there. Elementary usage can be divined from the ghci -- examples in Streaming.Prelude and perhaps from this rough -- beginning of a tutorial. Note also the streaming -- bytestring and streaming utils packages. Questions about -- usage can be put raised on StackOverflow with the tag -- [haskell-streaming], or as an issue on Github, or on the -- pipes list (the package understands itself as part of the pipes -- 'ecosystem'.) -- -- The simplest form of interoperation with pipes is accomplished -- with this isomorphism: -- --
-- Pipes.unfoldr Streaming.next :: Stream (Of a) m r -> Producer a m r -- Streaming.unfoldr Pipes.next :: Producer a m r -> Stream (Of a) m r ---- -- Interoperation with io-streams is thus: -- --
-- Streaming.reread IOStreams.read :: InputStream a -> Stream (Of a) IO () -- IOStreams.unfoldM Streaming.uncons :: Stream (Of a) IO () -> IO (InputStream a) ---- -- With conduit one might use, e.g.: -- --
-- Conduit.unfoldM Streaming.uncons :: Stream (Of a) m () -> Source m a -- \str -> Streaming.mapM_ Conduit.yield (hoist lift str) :: Stream (Of o) m r -> ConduitM i o m r -- \src -> hoist lift str $$ Conduit.mapM_ Streaming.yield :: Source m a -> Stream (Of a) m () ---- -- These conversions should never be more expensive than a single -- >-> or =$=. The simplest interoperation with -- regular Haskell lists is provided by, say -- --
-- Streaming.each :: [a] -> Stream (Of a) m () -- Streaming.toList_ :: Stream (Of a) m r -> m [a] ---- -- The latter of course accumulates the whole list in memory, and is -- mostly what we are trying to avoid. Every use of Prelude.mapM -- f should be reconceived as using the composition -- Streaming.toList_ . Streaming.mapM f . Streaming.each with a -- view to considering whether the accumulation required by -- Streaming.toList_ is really necessary. -- -- Here are the results of some microbenchmarks based on the -- benchmarks included in the machines package: -- -- -- Because these are microbenchmarks for individual functions, they -- represent a sort of "worst case"; many other factors can influence the -- speed of a complex program. @package streaming @version 0.2.3.1 module Data.Functor.Of -- | A left-strict pair; the base functor for streams of individual -- elements. data Of a b (:>) :: !a -> b -> Of a b infixr 5 :> instance GHC.Generics.Generic1 (Data.Functor.Of.Of a) instance GHC.Generics.Generic (Data.Functor.Of.Of a b) instance Data.Traversable.Traversable (Data.Functor.Of.Of a) instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Data.Functor.Of.Of a b) instance (GHC.Read.Read a, GHC.Read.Read b) => GHC.Read.Read (Data.Functor.Of.Of a b) instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Data.Functor.Of.Of a b) instance Data.Foldable.Foldable (Data.Functor.Of.Of a) instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Data.Functor.Of.Of a b) instance (Data.Data.Data a, Data.Data.Data b) => Data.Data.Data (Data.Functor.Of.Of a b) instance (GHC.Base.Semigroup a, GHC.Base.Semigroup b) => GHC.Base.Semigroup (Data.Functor.Of.Of a b) instance (GHC.Base.Monoid a, GHC.Base.Monoid b) => GHC.Base.Monoid (Data.Functor.Of.Of a b) instance GHC.Base.Functor (Data.Functor.Of.Of a) instance Data.Bifunctor.Bifunctor Data.Functor.Of.Of instance Data.Bifoldable.Bifoldable Data.Functor.Of.Of instance Data.Bitraversable.Bitraversable Data.Functor.Of.Of instance GHC.Base.Monoid a => GHC.Base.Applicative (Data.Functor.Of.Of a) instance GHC.Base.Monoid a => GHC.Base.Monad (Data.Functor.Of.Of a) instance GHC.Show.Show a => Data.Functor.Classes.Show1 (Data.Functor.Of.Of a) instance GHC.Classes.Eq a => Data.Functor.Classes.Eq1 (Data.Functor.Of.Of a) instance GHC.Classes.Ord a => Data.Functor.Classes.Ord1 (Data.Functor.Of.Of a) instance Data.Functor.Classes.Show2 Data.Functor.Of.Of instance Data.Functor.Classes.Eq2 Data.Functor.Of.Of instance Data.Functor.Classes.Ord2 Data.Functor.Of.Of module Streaming.Internal data Stream f m r Step :: !f (Stream f m r) -> Stream f m r Effect :: m (Stream f m r) -> Stream f m r Return :: r -> Stream f m r -- | Build a Stream by unfolding steps starting from a seed. See -- also the specialized unfoldr in the prelude. -- --
-- unfold inspect = id -- modulo the quotient we work with -- unfold Pipes.next :: Monad m => Producer a m r -> Stream ((,) a) m r -- unfold (curry (:>) . Pipes.next) :: Monad m => Producer a m r -> Stream (Of a) m r --unfold :: (Monad m, Functor f) => (s -> m (Either r (f s))) -> s -> Stream f m r -- | Repeat a functorial layer, command or instruction a fixed number of -- times. -- --
-- replicates n = takes n . repeats --replicates :: (Monad m, Functor f) => Int -> f () -> Stream f m () -- | Repeat a functorial layer (a "command" or "instruction") forever. repeats :: (Monad m, Functor f) => f () -> Stream f m r -- | Repeat an effect containing a functorial layer, command or instruction -- forever. repeatsM :: (Monad m, Functor f) => m (f ()) -> Stream f m r -- | Wrap an effect that returns a stream -- --
-- effect = join . lift --effect :: (Monad m, Functor f) => m (Stream f m r) -> Stream f m r -- | Wrap a new layer of a stream. So, e.g. -- --
-- S.cons :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) m r -- S.cons a str = wrap (a :> str) ---- -- and, recursively: -- --
-- S.each :: (Monad m, Foldable t) => t a -> Stream (Of a) m () -- S.each = foldr (\a b -> wrap (a :> b)) (return ()) ---- -- The two operations -- --
-- wrap :: (Monad m, Functor f ) => f (Stream f m r) -> Stream f m r -- effect :: (Monad m, Functor f ) => m (Stream f m r) -> Stream f m r ---- -- are fundamental. We can define the parallel operations yields -- and lift in terms of them -- --
-- yields :: (Monad m, Functor f ) => f r -> Stream f m r -- yields = wrap . fmap return -- lift :: (Monad m, Functor f ) => m r -> Stream f m r -- lift = effect . fmap return --wrap :: (Monad m, Functor f) => f (Stream f m r) -> Stream f m r -- | yields is like lift for items in the streamed -- functor. It makes a singleton or one-layer succession. -- --
-- lift :: (Monad m, Functor f) => m r -> Stream f m r -- yields :: (Monad m, Functor f) => f r -> Stream f m r ---- -- Viewed in another light, it is like a functor-general version of -- yield: -- --
-- S.yield a = yields (a :> ()) --yields :: (Monad m, Functor f) => f r -> Stream f m r -- | Reflect a church-encoded stream; cp. GHC.Exts.build -- --
-- streamFold return_ effect_ step_ (streamBuild psi) = psi return_ effect_ step_ --streamBuild :: (forall b. (r -> b) -> (m b -> b) -> (f b -> b) -> b) -> Stream f m r -- | Construct an infinite stream by cycling a finite one -- --
-- cycles = forever ---- --
-- >>> --cycles :: (Monad m, Functor f) => Stream f m () -> Stream f m r delays :: (MonadIO m, Applicative f) => Double -> Stream f m r -- | never interleaves the pure applicative action with the return -- of the monad forever. It is the empty of the Alternative -- instance, thus -- --
-- never <|> a = a -- a <|> never = a ---- -- and so on. If w is a monoid then never :: Stream (Of w) m r -- is the infinite sequence of mempty, and str1 <|> -- str2 appends the elements monoidally until one of streams ends. -- Thus we have, e.g. -- --
-- >>> S.stdoutLn $ S.take 2 $ S.stdinLn <|> S.repeat " " <|> S.stdinLn <|> S.repeat " " <|> S.stdinLn -- 1<Enter> -- 2<Enter> -- 3<Enter> -- 1 2 3 -- 4<Enter> -- 5<Enter> -- 6<Enter> -- 4 5 6 ---- -- This is equivalent to -- --
-- >>> S.stdoutLn $ S.take 2 $ foldr (<|>) never [S.stdinLn, S.repeat " ", S.stdinLn, S.repeat " ", S.stdinLn ] ---- -- Where f is a monad, (<|>) sequences the -- conjoined streams stepwise. See the definition of paste -- here, where the separate steps are bytestreams corresponding to -- the lines of a file. -- -- Given, say, -- --
-- data Branch r = Branch r r deriving Functor -- add obvious applicative instance ---- -- then never :: Stream Branch Identity r is the pure infinite -- binary tree with (inaccessible) rs in its leaves. Given two -- binary trees, tree1 <|> tree2 intersects them, -- preserving the leaves that came first, so tree1 <|> never = -- tree1 -- -- Stream Identity m r is an action in m that is -- indefinitely delayed. Such an action can be constructed with e.g. -- untilJust. -- --
-- untilJust :: (Monad m, Applicative f) => m (Maybe r) -> Stream f m r ---- -- Given two such items, <|> instance races them. It is -- thus the iterative monad transformer specially defined in -- Control.Monad.Trans.Iter -- -- So, for example, we might write -- --
-- >>> let justFour str = if length str == 4 then Just str else Nothing -- -- >>> let four = untilJust (fmap justFour getLine) -- -- >>> run four -- one<Enter> -- two<Enter> -- three<Enter> -- four<Enter> -- "four" ---- -- The Alternative instance in Control.Monad.Trans.Free is -- avowedly wrong, though no explanation is given for this. never :: (Monad m, Applicative f) => Stream f m r -- | Repeat a untilJust :: (Monad m, Applicative f) => m (Maybe r) -> Stream f m r -- | Interpolate a layer at each segment. This specializes to e.g. -- --
-- intercalates :: (Monad m, Functor f) => Stream f m () -> Stream (Stream f m) m r -> Stream f m r --intercalates :: (Monad m, Monad (t m), MonadTrans t) => t m x -> Stream (t m) m r -> t m r -- | Dissolves the segmentation into layers of Stream f m layers. concats :: (Monad m, Functor f) => Stream (Stream f m) m r -> Stream f m r -- | Specialized fold following the usage of -- Control.Monad.Trans.Free -- --
-- iterT alg = streamFold return join alg -- iterT alg = runIdentityT . iterTM (IdentityT . alg . fmap runIdentityT) --iterT :: (Functor f, Monad m) => (f (m a) -> m a) -> Stream f m a -> m a -- | Specialized fold following the usage of -- Control.Monad.Trans.Free -- --
-- iterTM alg = streamFold return (join . lift) -- iterTM alg = iterT alg . hoist lift --iterTM :: (Functor f, Monad m, MonadTrans t, Monad (t m)) => (f (t m a) -> t m a) -> Stream f m a -> t m a -- | Map a stream to its church encoding; compare Data.List.foldr. -- destroyExposed may be more efficient in some cases when -- applicable, but it is less safe. -- --
-- destroy s construct eff done -- = eff . iterT (return . construct . fmap eff) . fmap done $ s -- --destroy :: (Functor f, Monad m) => Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b -- | streamFold reorders the arguments of destroy to be more -- akin to foldr It is more convenient to query in ghci to -- figure out what kind of 'algebra' you need to write. -- --
-- >>> :t streamFold return join -- (Monad m, Functor f) => -- (f (m a) -> m a) -> Stream f m a -> m a -- iterT ---- --
-- >>> :t streamFold return (join . lift) -- (Monad m, Monad (t m), Functor f, MonadTrans t) => -- (f (t m a) -> t m a) -> Stream f m a -> t m a -- iterTM ---- --
-- >>> :t streamFold return effect -- (Monad m, Functor f, Functor g) => -- (f (Stream g m r) -> Stream g m r) -> Stream f m r -> Stream g m r ---- --
-- >>> :t \f -> streamFold return effect (wrap . f) -- (Monad m, Functor f, Functor g) => -- (f (Stream g m a) -> g (Stream g m a)) -- -> Stream f m a -> Stream g m a -- maps ---- --
-- >>> :t \f -> streamFold return effect (effect . fmap wrap . f) -- (Monad m, Functor f, Functor g) => -- (f (Stream g m a) -> m (g (Stream g m a))) -- -> Stream f m a -> Stream g m a -- mapped ---- --
-- streamFold done eff construct -- = eff . iterT (return . construct . fmap eff) . fmap done --streamFold :: (Functor f, Monad m) => (r -> b) -> (m b -> b) -> (f b -> b) -> Stream f m r -> b -- | Inspect the first stage of a freely layered sequence. Compare -- Pipes.next and the replica Streaming.Prelude.next. -- This is the uncons for the general unfold. -- --
-- unfold inspect = id -- Streaming.Prelude.unfoldr StreamingPrelude.next = id --inspect :: Monad m => Stream f m r -> m (Either r (f (Stream f m r))) -- | Map layers of one functor to another with a transformation. Compare -- hoist, which has a similar effect on the monadic parameter. -- --
-- maps id = id -- maps f . maps g = maps (f . g) --maps :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation involving -- the base monad. maps is more fundamental than mapsM, -- which is best understood as a convenience for effecting this frequent -- composition: -- --
-- mapsM phi = decompose . maps (Compose . phi) ---- -- The streaming prelude exports the same function under the better name -- mapped, which overlaps with the lens libraries. mapsM :: (Monad m, Functor f) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation. Compare -- hoist, which has a similar effect on the monadic parameter. -- --
-- mapsPost id = id -- mapsPost f . mapsPost g = mapsPost (f . g) -- mapsPost f = maps f ---- -- mapsPost is essentially the same as maps, but it -- imposes a Functor constraint on its target functor rather than -- its source functor. It should be preferred if fmap is cheaper -- for the target functor than for the source functor. mapsPost :: forall m f g r. (Monad m, Functor g) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation involving -- the base monad. mapsMPost is essentially the same as -- mapsM, but it imposes a Functor constraint on its target -- functor rather than its source functor. It should be preferred if -- fmap is cheaper for the target functor than for the source -- functor. -- -- mapsPost is more fundamental than mapsMPost, which -- is best understood as a convenience for effecting this frequent -- composition: -- --
-- mapsMPost phi = decompose . mapsPost (Compose . phi) ---- -- The streaming prelude exports the same function under the better name -- mappedPost, which overlaps with the lens libraries. mapsMPost :: forall m f g r. (Monad m, Functor g) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | A less-efficient version of hoist that works properly even when -- its argument is not a monad morphism. -- --
-- hoistUnexposed = hoist . unexposed --hoistUnexposed :: (Monad m, Functor f) => (forall a. m a -> n a) -> Stream f m r -> Stream f n r -- | Rearrange a succession of layers of the form Compose m (f x). -- -- we could as well define decompose by mapsM: -- --
-- decompose = mapped getCompose ---- -- but mapped is best understood as: -- --
-- mapped phi = decompose . maps (Compose . phi) ---- -- since maps and hoist are the really fundamental -- operations that preserve the shape of the stream: -- --
-- maps :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- hoist :: (Monad m, Functor f) => (forall a. m a -> n a) -> Stream f m r -> Stream f n r --decompose :: (Monad m, Functor f) => Stream (Compose m f) m r -> Stream f m r -- | Map each layer to an effect, and run them all. mapsM_ :: (Functor f, Monad m) => (forall x. f x -> m x) -> Stream f m r -> m r -- | Run the effects in a stream that merely layers effects. run :: Monad m => Stream m m r -> m r -- | Make it possible to 'run' the underlying transformed monad. distribute :: (Monad m, Functor f, MonadTrans t, MFunctor t, Monad (t (Stream f m))) => Stream f (t m) r -> t (Stream f m) r -- | Group layers in an alternating stream into adjoining sub-streams of -- one type or another. groups :: (Monad m, Functor f, Functor g) => Stream (Sum f g) m r -> Stream (Sum (Stream f m) (Stream g m)) m r -- | Break a stream into substreams each with n functorial layers. -- --
-- >>> S.print $ mapped S.sum $ chunksOf 2 $ each [1,1,1,1,1] -- 2 -- 2 -- 1 --chunksOf :: (Monad m, Functor f) => Int -> Stream f m r -> Stream (Stream f m) m r -- | Split a succession of layers after some number, returning a streaming -- or effectful pair. -- --
-- >>> rest <- S.print $ S.splitAt 1 $ each [1..3] -- 1 -- -- >>> S.print rest -- 2 -- 3 ---- --
-- splitAt 0 = return -- splitAt n >=> splitAt m = splitAt (m+n) ---- -- Thus, e.g. -- --
-- >>> rest <- S.print $ splitsAt 2 >=> splitsAt 2 $ each [1..5] -- 1 -- 2 -- 3 -- 4 -- -- >>> S.print rest -- 5 --splitsAt :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Stream f m r) takes :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m () cutoff :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Maybe r) -- | Zip two streams together. The zipsWith' function should -- generally be preferred for efficiency. zipsWith :: forall f g h m r. (Monad m, Functor h) => (forall x y. f x -> g y -> h (x, y)) -> Stream f m r -> Stream g m r -> Stream h m r -- | Zip two streams together. zipsWith' :: forall f g h m r. Monad m => (forall x y p. (x -> y -> p) -> f x -> g y -> h p) -> Stream f m r -> Stream g m r -> Stream h m r zips :: (Monad m, Functor f, Functor g) => Stream f m r -> Stream g m r -> Stream (Compose f g) m r unzips :: (Monad m, Functor f, Functor g) => Stream (Compose f g) m r -> Stream f (Stream g m) r -- | Interleave functor layers, with the effects of the first preceding the -- effects of the second. When the first stream runs out, any remaining -- effects in the second are ignored. -- --
-- interleaves = zipsWith (liftA2 (,)) ---- --
-- >>> let paste = \a b -> interleaves (Q.lines a) (maps (Q.cons' '\t') (Q.lines b)) -- -- >>> Q.stdout $ Q.unlines $ paste "hello\nworld\n" "goodbye\nworld\n" -- hello goodbye -- world world --interleaves :: (Monad m, Applicative h) => Stream h m r -> Stream h m r -> Stream h m r -- | Given a stream on a sum of functors, make it a stream on the left -- functor, with the streaming on the other functor as the governing -- monad. This is useful for acting on one or the other functor with a -- fold, leaving the other material for another treatment. It generalizes -- partitionEithers, but actually streams properly. -- --
-- >>> let odd_even = S.maps (S.distinguish even) $ S.each [1..10::Int] -- -- >>> :t separate odd_even -- separate odd_even -- :: Monad m => Stream (Of Int) (Stream (Of Int) m) () ---- -- Now, for example, it is convenient to fold on the left and right -- values separately: -- --
-- >>> S.toList $ S.toList $ separate odd_even -- [2,4,6,8,10] :> ([1,3,5,7,9] :> ()) ---- -- Or we can write them to separate files or whatever: -- --
-- >>> S.writeFile "even.txt" . S.show $ S.writeFile "odd.txt" . S.show $ S.separate odd_even -- -- >>> :! cat even.txt -- 2 -- 4 -- 6 -- 8 -- 10 -- -- >>> :! cat odd.txt -- 1 -- 3 -- 5 -- 7 -- 9 ---- -- Of course, in the special case of Stream (Of a) m r, we can -- achieve the above effects more simply by using copy -- --
-- >>> S.toList . S.filter even $ S.toList . S.filter odd $ S.copy $ each [1..10::Int] -- [2,4,6,8,10] :> ([1,3,5,7,9] :> ()) ---- -- But separate and unseparate are functor-general. separate :: (Monad m, Functor f, Functor g) => Stream (Sum f g) m r -> Stream f (Stream g m) r unseparate :: (Monad m, Functor f, Functor g) => Stream f (Stream g m) r -> Stream (Sum f g) m r -- | If Of had a Comonad instance, then we'd have -- --
-- copy = expand extend ---- -- See expandPost for a version that requires a Functor g -- instance instead. expand :: (Monad m, Functor f) => (forall a b. (g a -> b) -> f a -> h b) -> Stream f m r -> Stream g (Stream h m) r -- | If Of had a Comonad instance, then we'd have -- --
-- copy = expandPost extend ---- -- See expand for a version that requires a Functor f -- instance instead. expandPost :: (Monad m, Functor g) => (forall a b. (g a -> b) -> f a -> h b) -> Stream f m r -> Stream g (Stream h m) r -- | Swap the order of functors in a sum of functors. -- --
-- >>> S.toList $ S.print $ separate $ maps S.switch $ maps (S.distinguish (=='a')) $ S.each "banana" -- 'a' -- 'a' -- 'a' -- "bnn" :> () -- -- >>> S.toList $ S.print $ separate $ maps (S.distinguish (=='a')) $ S.each "banana" -- 'b' -- 'n' -- 'n' -- "aaa" :> () --switch :: Sum f g r -> Sum g f r -- | This is akin to the observe of Pipes.Internal . It -- reeffects the layering in instances of Stream f m r so that -- it replicates that of FreeT. unexposed :: (Functor f, Monad m) => Stream f m r -> Stream f m r -- | The same as hoist, but explicitly named to indicate that it is -- not entirely safe. In particular, its argument must be a monad -- morphism. hoistExposed :: (Functor m, Functor f) => (forall b. m b -> n b) -> Stream f m a -> Stream f n a -- | The same as hoistExposed, but with a Functor constraint -- on the target rather than the source. This must be used only with a -- monad morphism. hoistExposedPost :: (Functor n, Functor f) => (forall b. m b -> n b) -> Stream f m a -> Stream f n a -- | Deprecated: Use maps instead. mapsExposed :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- | Deprecated: Use mapsM instead. mapsMExposed :: (Monad m, Functor f) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | Map a stream directly to its church encoding; compare -- Data.List.foldr It permits distinctions that should be -- hidden, as can be seen from e.g. -- --
-- isPure stream = destroyExposed (const True) (const False) (const True) ---- -- and similar nonsense. The crucial constraint is that the m x -> -- x argument is an Eilenberg-Moore algebra. See Atkey, -- "Reasoning about Stream Processing with Effects" -- -- When in doubt, use destroy instead. destroyExposed :: (Functor f, Monad m) => Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b instance (GHC.Base.Monad m, GHC.Show.Show r, GHC.Show.Show (m Streaming.Internal.ShowSWrapper), GHC.Show.Show (f (Streaming.Internal.Stream f m r))) => GHC.Show.Show (Streaming.Internal.Stream f m r) instance (GHC.Base.Monad m, GHC.Base.Functor f, GHC.Show.Show (m Streaming.Internal.ShowSWrapper), GHC.Show.Show (f Streaming.Internal.ShowSWrapper)) => Data.Functor.Classes.Show1 (Streaming.Internal.Stream f m) instance GHC.Show.Show Streaming.Internal.ShowSWrapper instance (GHC.Base.Monad m, GHC.Classes.Eq (m (Data.Either.Either r (f (Streaming.Internal.Stream f m r))))) => GHC.Classes.Eq (Streaming.Internal.Stream f m r) instance (GHC.Base.Monad m, GHC.Classes.Ord (m (Data.Either.Either r (f (Streaming.Internal.Stream f m r))))) => GHC.Classes.Ord (Streaming.Internal.Stream f m r) instance (GHC.Base.Monad m, GHC.Base.Functor f, Data.Functor.Classes.Eq1 m, Data.Functor.Classes.Eq1 f) => Data.Functor.Classes.Eq1 (Streaming.Internal.Stream f m) instance (GHC.Base.Monad m, GHC.Base.Functor f, Data.Functor.Classes.Ord1 m, Data.Functor.Classes.Ord1 f) => Data.Functor.Classes.Ord1 (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, GHC.Base.Monad m) => GHC.Base.Functor (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, GHC.Base.Monad m) => GHC.Base.Monad (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, Control.Monad.Fail.MonadFail m) => Control.Monad.Fail.MonadFail (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, GHC.Base.Monad m) => GHC.Base.Applicative (Streaming.Internal.Stream f m) instance (GHC.Base.Applicative f, GHC.Base.Monad m) => GHC.Base.Alternative (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, GHC.Base.Monad m, GHC.Base.Semigroup w) => GHC.Base.Semigroup (Streaming.Internal.Stream f m w) instance (GHC.Base.Functor f, GHC.Base.Monad m, GHC.Base.Monoid w) => GHC.Base.Monoid (Streaming.Internal.Stream f m w) instance (GHC.Base.Applicative f, GHC.Base.Monad m) => GHC.Base.MonadPlus (Streaming.Internal.Stream f m) instance GHC.Base.Functor f => Control.Monad.Trans.Class.MonadTrans (Streaming.Internal.Stream f) instance GHC.Base.Functor f => Control.Monad.Morph.MFunctor (Streaming.Internal.Stream f) instance GHC.Base.Functor f => Control.Monad.Morph.MMonad (Streaming.Internal.Stream f) instance (Control.Monad.IO.Class.MonadIO m, GHC.Base.Functor f) => Control.Monad.IO.Class.MonadIO (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, Control.Monad.Reader.Class.MonadReader r m) => Control.Monad.Reader.Class.MonadReader r (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, Control.Monad.State.Class.MonadState s m) => Control.Monad.State.Class.MonadState s (Streaming.Internal.Stream f m) instance (GHC.Base.Functor f, Control.Monad.Error.Class.MonadError e m) => Control.Monad.Error.Class.MonadError e (Streaming.Internal.Stream f m) -- | The names exported by this module are closely modeled on those in -- Prelude and Data.List, but also on -- Pipes.Prelude, Pipes.Group and Pipes.Parse. The -- module may be said to give independent expression to the conception of -- Producer / Source / Generator manipulation articulated in the latter -- two modules. Because we dispense with piping and conduiting, the -- distinction between all of these modules collapses. Some things are -- lost but much is gained: on the one hand, everything comes much closer -- to ordinary beginning Haskell programming and, on the other, acquires -- the plasticity of programming directly with a general free monad type. -- The leading type, Stream (Of a) m r is chosen to permit an -- api that is as close as possible to that of Data.List and the -- Prelude. -- -- Import qualified thus: -- --
-- import Streaming -- import qualified Streaming.Prelude as S ---- -- For the examples below, one sometimes needs -- --
-- import Streaming.Prelude (each, yield, next, mapped, stdoutLn, stdinLn) -- import Data.Function ((&)) ---- -- Other libraries that come up in passing are -- --
-- import qualified Control.Foldl as L -- cabal install foldl -- import qualified Pipes as P -- 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 | -- -------------------------------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------------------------------- -- ByteString m () | Producer ByteString m () | Source m ByteString | InputStream ByteString -- -------------------------------------------------------------------------------------------------------------------- --module Streaming.Prelude -- | A left-strict pair; the base functor for streams of individual -- elements. data Of a b (:>) :: !a -> b -> Of a b infixr 5 :> -- | A singleton stream -- --
-- >>> stdoutLn $ yield "hello" -- hello ---- --
-- >>> S.sum $ do {yield 1; yield 2; yield 3}
-- 6 :> ()
--
--
--
-- >>> let number = lift (putStrLn "Enter a number:") >> lift readLn >>= yield :: Stream (Of Int) IO ()
--
-- >>> S.toList $ do {number; number; number}
-- Enter a number:
-- 1<Enter>
-- Enter a number:
-- 2<Enter>
-- Enter a number:
-- 3<Enter>
-- [1,2,3] :> ()
--
yield :: Monad m => a -> Stream (Of a) m ()
-- | Stream the elements of a pure, foldable container.
--
-- -- >>> S.print $ each [1..3] -- 1 -- 2 -- 3 --each :: (Monad m, Foldable f) => f a -> Stream (Of a) m () -- | View standard input as a Stream (Of String) m r. By contrast, -- stdoutLn renders a Stream (Of String) m r to standard -- output. The names follow Pipes.Prelude -- --
-- >>> stdoutLn stdinLn -- hello<Enter> -- hello -- world<Enter> -- world -- ^CInterrupted. ---- --
-- >>> stdoutLn $ S.map reverse stdinLn -- hello<Enter> -- olleh -- world<Enter> -- dlrow -- ^CInterrupted. --stdinLn :: MonadIO m => Stream (Of String) m () -- | Read values from stdin, ignoring failed parses. -- --
-- >>> :set -XTypeApplications -- -- >>> S.sum $ S.take 2 (S.readLn @IO @Int) -- 10<Enter> -- 12<Enter> -- 22 :> () ---- --
-- >>> S.toList $ S.take 2 (S.readLn @IO @Int) -- 10<Enter> -- 1@#$%^&*\<Enter> -- 12<Enter> -- [10,12] :> () --readLn :: (MonadIO m, Read a) => Stream (Of a) m () -- | Read Strings from a Handle using hGetLine -- -- Terminates on end of input -- --
-- >>> IO.withFile "/usr/share/dict/words" IO.ReadMode $ S.stdoutLn . S.take 3 . S.drop 50000 . S.fromHandle -- deflagrator -- deflate -- deflation --fromHandle :: MonadIO m => Handle -> Stream (Of String) m () -- | Read the lines of a file, using a function of the type: -- 'Stream (Of String) IO () -> -- IO a' to turn the stream into a value of type 'IO -- a'. -- --
-- >>> S.writeFile "lines.txt" $ S.take 2 S.stdinLn -- hello<Enter> -- world<Enter> -- -- >>> S.readFile "lines.txt" S.print -- "hello" -- "world" --readFile :: FilePath -> (Stream (Of String) IO () -> IO a) -> IO a -- | Iterate a pure function from a seed value, streaming the results -- forever iterate :: Monad m => (a -> a) -> a -> Stream (Of a) m r -- | Iterate a monadic function from a seed value, streaming the results -- forever iterateM :: Monad m => (a -> m a) -> m a -> Stream (Of a) m r -- | Repeat an element ad inf. . -- --
-- >>> S.print $ S.take 3 $ S.repeat 1 -- 1 -- 1 -- 1 --repeat :: Monad m => a -> Stream (Of a) m r -- | Repeat a monadic action ad inf., streaming its results. -- --
-- >>> S.toList $ S.take 2 $ repeatM getLine -- one<Enter> -- two<Enter> -- ["one","two"] --repeatM :: Monad m => m a -> Stream (Of a) m r -- | Repeat an element several times. replicate :: Monad m => Int -> a -> Stream (Of a) m () untilLeft :: Monad m => m (Either r a) -> Stream (Of a) m r untilRight :: Monad m => m (Either a r) -> Stream (Of a) m r -- | Cycle repeatedly through the layers of a stream, ad inf. This -- function is functor-general -- --
-- cycle = forever ---- --
-- >>> rest <- S.print $ S.splitAt 3 $ S.cycle (yield True >> yield False) -- True -- False -- True -- -- >>> S.print $ S.take 3 rest -- False -- True -- False --cycle :: (Monad m, Functor f) => Stream f m r -> Stream f m s -- | Repeat an action several times, streaming its results. -- --
-- >>> S.print $ S.replicateM 2 getCurrentTime -- 2015-08-18 00:57:36.124508 UTC -- 2015-08-18 00:57:36.124785 UTC --replicateM :: Monad m => Int -> m a -> Stream (Of a) m () -- | An infinite stream of enumerable values, starting from a given value. -- It is the same as S.iterate succ. Because their return type -- is polymorphic, enumFrom, enumFromThen and -- iterate are useful with functions like zip and -- zipWith, which require the zipped streams to have the same -- return type. -- -- For example, with each [1..] the following bit of -- connect-and-resume would not compile: -- --
-- >>> rest <- S.print $ S.zip (S.enumFrom 1) $ S.splitAt 3 $ S.each ['a'..'z'] -- (1,'a') -- (2,'b') -- (3,'c') -- -- >>> S.print $ S.take 3 rest -- 'd' -- 'e' -- 'f' --enumFrom :: (Monad m, Enum n) => n -> Stream (Of n) m r -- | An infinite sequence of enumerable values at a fixed distance, -- determined by the first and second values. See the discussion of -- enumFrom -- --
-- >>> S.print $ S.take 3 $ S.enumFromThen 100 200 -- 100 -- 200 -- 300 --enumFromThen :: (Monad m, Enum a) => a -> a -> Stream (Of a) m r -- | Build a Stream by unfolding steps starting from a seed. In -- particular note that S.unfoldr S.next = id. -- -- The seed can of course be anything, but this is one natural way to -- consume a pipes Producer. Consider: -- --
-- >>> S.stdoutLn $ S.take 2 $ S.unfoldr Pipes.next Pipes.stdinLn -- hello<Enter> -- hello -- goodbye<Enter> -- goodbye ---- --
-- >>> S.stdoutLn $ S.unfoldr Pipes.next (Pipes.stdinLn >-> Pipes.take 2) -- hello<Enter> -- hello -- goodbye<Enter> -- goodbye ---- --
-- >>> S.effects $ S.unfoldr Pipes.next (Pipes.stdinLn >-> Pipes.take 2 >-> Pipes.stdoutLn) -- hello<Enter> -- hello -- goodbye<Enter> -- goodbye ---- -- Pipes.unfoldr S.next similarly unfolds a -- Pipes.Producer from a stream. unfoldr :: Monad m => (s -> m (Either r (a, s))) -> s -> Stream (Of a) m r -- | Write Strings to stdout using putStrLn; -- terminates on a broken output pipe (The name and implementation are -- modelled on the Pipes.Prelude stdoutLn). -- --
-- >>> S.stdoutLn $ S.take 3 $ S.each $ words "one two three four five" -- one -- two -- three --stdoutLn :: MonadIO m => Stream (Of String) m () -> m () -- | Write Strings to stdout using putStrLn -- -- Unlike stdoutLn, stdoutLn' does not handle a broken -- output pipe. Thus it can have a polymorphic return value, rather than -- (), and this kind of "connect and resume" is possible: -- --
-- >>> rest <- S.stdoutLn' $ S.show $ S.splitAt 3 (each [1..5]) -- 1 -- 2 -- 3 -- -- >>> S.toList rest -- [4,5] :> () --stdoutLn' :: MonadIO m => Stream (Of String) m r -> m r -- | Reduce a stream to its return value with a monadic action. -- --
-- >>> S.mapM_ Prelude.print $ each [1..3] -- 1 -- 2 -- 3 ---- --
-- >>> rest <- S.mapM_ Prelude.print $ S.splitAt 3 $ each [1..10] -- 1 -- 2 -- 3 -- -- >>> S.sum rest -- 49 :> () --mapM_ :: Monad m => (a -> m x) -> Stream (Of a) m r -> m r -- | Print the elements of a stream as they arise. -- --
-- >>> S.print $ S.take 2 S.stdinLn -- hello<Enter> -- "hello" -- world<Enter> -- "world" --print :: (MonadIO m, Show a) => Stream (Of a) m r -> m r -- | Write a succession of strings to a handle as separate lines. -- --
-- >>> S.toHandle IO.stdout $ each (words "one two three") -- one -- two -- three --toHandle :: MonadIO m => Handle -> Stream (Of String) m r -> m r -- | Write a series of Strings as lines to a file. -- --
-- >>> S.writeFile "lines.txt" $ S.take 2 S.stdinLn -- hello<Enter> -- world<Enter> ---- --
-- >>> S.readFile "lines.txt" S.stdoutLn -- hello -- world --writeFile :: FilePath -> Stream (Of String) IO r -> IO r -- | Reduce a stream, performing its actions but ignoring its elements. -- --
-- >>> rest <- S.effects $ S.splitAt 2 $ each [1..5] -- -- >>> S.print rest -- 3 -- 4 -- 5 ---- -- effects should be understood together with copy and is -- subject to the rules -- --
-- S.effects . S.copy = id -- hoist S.effects . S.copy = id ---- -- The similar effects and copy operations in -- Data.ByteString.Streaming obey the same rules. effects :: Monad m => Stream (Of a) m r -> m r -- | Remove the elements from a stream of values, retaining the structure -- of layers. erase :: Monad m => Stream (Of a) m r -> Stream Identity m r -- | Where a transformer returns a stream, run the effects of the stream, -- keeping the return value. This is usually used at the type -- --
-- drained :: Monad m => Stream (Of a) m (Stream (Of b) m r) -> Stream (Of a) m r -- drained = join . fmap (lift . effects) ---- -- Here, for example, we split a stream in two places and throw out the -- middle segment: -- --
-- >>> rest <- S.print $ S.drained $ S.splitAt 2 $ S.splitAt 5 $ each [1..7] -- 1 -- 2 -- -- >>> S.print rest -- 6 -- 7 ---- -- In particular, we can define versions of take and -- takeWhile which retrieve the return value of the rest of the -- stream - and which can thus be used with maps: -- --
-- take' n = S.drained . S.splitAt n -- takeWhile' thus = S.drained . S.span thus --drained :: (Monad m, Monad (t m), MonadTrans t) => t m (Stream (Of a) m r) -> t m r -- | Standard map on the elements of a stream. -- --
-- >>> S.stdoutLn $ S.map reverse $ each (words "alpha beta") -- ahpla -- ateb --map :: Monad m => (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r -- | Replace each element of a stream with the result of a monadic action -- --
-- >>> S.print $ S.mapM readIORef $ S.chain (\ior -> modifyIORef ior (*100)) $ S.mapM newIORef $ each [1..6] -- 100 -- 200 -- 300 -- 400 -- 500 -- 600 ---- -- See also chain for a variant of this which ignores the return -- value of the function and just uses the side effects. mapM :: Monad m => (a -> m b) -> Stream (Of a) m r -> Stream (Of b) m r -- | Map layers of one functor to another with a transformation. Compare -- hoist, which has a similar effect on the monadic parameter. -- --
-- maps id = id -- maps f . maps g = maps (f . g) --maps :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation. Compare -- hoist, which has a similar effect on the monadic parameter. -- --
-- mapsPost id = id -- mapsPost f . mapsPost g = mapsPost (f . g) -- mapsPost f = maps f ---- -- mapsPost is essentially the same as maps, but it -- imposes a Functor constraint on its target functor rather than -- its source functor. It should be preferred if fmap is cheaper -- for the target functor than for the source functor. mapsPost :: forall m f g r. (Monad m, Functor g) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation involving -- the base monad. -- -- This function is completely functor-general. It is often useful with -- the more concrete type -- --
-- mapped :: (forall x. Stream (Of a) IO x -> IO (Of b x)) -> Stream (Stream (Of a) IO) IO r -> Stream (Of b) IO r ---- -- to process groups which have been demarcated in an effectful, -- IO-based stream by grouping functions like group, -- split or breaks. Summary functions like fold, -- foldM, mconcat or toList are often used to define -- the transformation argument. For example: -- --
-- >>> S.toList_ $ S.mapped S.toList $ S.split 'c' (S.each "abcde") -- ["ab","de"] ---- -- maps and mapped obey these rules: -- --
-- maps id = id -- mapped return = id -- maps f . maps g = maps (f . g) -- mapped f . mapped g = mapped (f <=< g) -- maps f . mapped g = mapped (fmap f . g) -- mapped f . maps g = mapped (f <=< fmap g) ---- -- maps is more fundamental than mapped, which is best -- understood as a convenience for effecting this frequent composition: -- --
-- mapped phi = decompose . maps (Compose . phi) --mapped :: (Monad m, Functor f) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | A version of mapped that imposes a Functor constraint on -- the target functor rather than the source functor. This version should -- be preferred if fmap on the target functor is cheaper. mappedPost :: (Monad m, Functor g) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | for replaces each element of a stream with an associated -- stream. Note that the associated stream may layer any functor. for :: (Monad m, Functor f) => Stream (Of a) m r -> (a -> Stream f m x) -> Stream f m r -- | Replace each element in a stream of individual Haskell values (a -- Stream (Of a) m r) with an associated functorial -- step. -- --
-- for str f = concats (with str f) -- with str f = for str (yields . f) -- with str f = maps (\(a:>r) -> r <$ f a) str -- with = flip subst -- subst = flip with ---- --
-- >>> with (each [1..3]) (yield . Prelude.show) & intercalates (yield "--") & S.stdoutLn -- 1 -- -- -- 2 -- -- -- 3 --with :: (Monad m, Functor f) => Stream (Of a) m r -> (a -> f x) -> Stream f m r -- | Replace each element in a stream of individual values with a -- functorial layer of any sort. subst = flip with and is more -- convenient in a sequence of compositions that transform a stream. -- --
-- with = flip subst -- for str f = concats $ subst f str -- subst f = maps (\(a:>r) -> r <$ f a) -- S.concat = concats . subst each --subst :: (Monad m, Functor f) => (a -> f x) -> Stream (Of a) m r -> Stream f m r -- | Duplicate the content of stream, so that it can be acted on twice in -- different ways, but without breaking streaming. Thus, with each -- [1,2] I might do: -- --
-- >>> S.print $ each ["one","two"] -- "one" -- "two" -- -- >>> S.stdoutLn $ each ["one","two"] -- one -- two ---- -- With copy, I can do these simultaneously: -- --
-- >>> S.print $ S.stdoutLn $ S.copy $ each ["one","two"] -- "one" -- one -- "two" -- two ---- -- copy should be understood together with effects and is -- subject to the rules -- --
-- S.effects . S.copy = id -- hoist S.effects . S.copy = id ---- -- The similar operations in Streaming obey the same rules. -- -- Where the actions you are contemplating are each simple folds over the -- elements, or a selection of elements, then the coupling of the folds -- is often more straightforwardly effected with Foldl, e.g. -- --
-- >>> L.purely S.fold (liftA2 (,) L.sum L.product) $ each [1..10] -- (55,3628800) :> () ---- -- rather than -- --
-- >>> S.sum $ S.product . S.copy $ each [1..10] -- 55 :> (3628800 :> ()) ---- -- A Control.Foldl fold can be altered to act on a selection of -- elements by using handles on an appropriate lens. Some such -- manipulations are simpler and more List-like, using -- copy: -- --
-- >>> L.purely S.fold (liftA2 (,) (L.handles (L.filtered odd) L.sum) (L.handles (L.filtered even) L.product)) $ each [1..10] -- (25,3840) :> () ---- -- becomes -- --
-- >>> S.sum $ S.filter odd $ S.product $ S.filter even $ S.copy $ each [1..10] -- 25 :> (3840 :> ()) ---- -- or using store -- --
-- >>> S.sum $ S.filter odd $ S.store (S.product . S.filter even) $ each [1..10] -- 25 :> (3840 :> ()) ---- -- But anything that fold of a Stream (Of a) m r into e.g. an -- m (Of b r) that has a constraint on m that is -- carried over into Stream f m - e.g. Monad, -- MonadIO, MonadResource, etc. can be used on the -- stream. Thus, I can fold over different groupings of the original -- stream: -- --
-- >>> (S.toList . mapped S.toList . chunksOf 5) $ (S.toList . mapped S.toList . chunksOf 3) $ S.copy $ each [1..10] -- [[1,2,3,4,5],[6,7,8,9,10]] :> ([[1,2,3],[4,5,6],[7,8,9],[10]] :> ()) ---- -- The procedure can be iterated as one pleases, as one can see from this -- (otherwise unadvisable!) example: -- --
-- >>> (S.toList . mapped S.toList . chunksOf 4) $ (S.toList . mapped S.toList . chunksOf 3) $ S.copy $ (S.toList . mapped S.toList . chunksOf 2) $ S.copy $ each [1..12] -- [[1,2,3,4],[5,6,7,8],[9,10,11,12]] :> ([[1,2,3],[4,5,6],[7,8,9],[10,11,12]] :> ([[1,2],[3,4],[5,6],[7,8],[9,10],[11,12]] :> ())) ---- -- copy can be considered a special case of expand: -- --
-- copy = expand $ \p (a :> as) -> a :> p (a :> as) ---- -- If Of were an instance of Comonad, then one could write -- --
-- copy = expand extend --copy :: Monad m => Stream (Of a) m r -> Stream (Of a) (Stream (Of a) m) r -- | An alias for copy. duplicate :: Monad m => Stream (Of a) m r -> Stream (Of a) (Stream (Of a) m) r -- | Store the result of any suitable fold over a stream, keeping the -- stream for further manipulation. store f = f . copy : -- --
-- >>> S.print $ S.store S.product $ each [1..4] -- 1 -- 2 -- 3 -- 4 -- 24 :> () ---- --
-- >>> S.print $ S.store S.sum $ S.store S.product $ each [1..4] -- 1 -- 2 -- 3 -- 4 -- 10 :> (24 :> ()) ---- -- Here the sum (10) and the product (24) have been 'stored' for use when -- finally we have traversed the stream with print . Needless to -- say, a second pass is excluded conceptually, so the folds -- that you apply successively with store are performed -- simultaneously, and in constant memory -- as they would be if, say, -- you linked them together with Control.Fold: -- --
-- >>> L.impurely S.foldM (liftA3 (\a b c -> (b, c)) (L.sink Prelude.print) (L.generalize L.sum) (L.generalize L.product)) $ each [1..4] -- 1 -- 2 -- 3 -- 4 -- (10,24) :> () ---- -- Fusing folds after the fashion of Control.Foldl will -- generally be a bit faster than the corresponding succession of uses of -- store, but by constant factor that will be completely dwarfed -- when any IO is at issue. -- -- But store / copy is much more powerful, as you -- can see by reflecting on uses like this: -- --
-- >>> S.sum $ S.store (S.sum . mapped S.product . chunksOf 2) $ S.store (S.product . mapped S.sum . chunksOf 2) $ each [1..6] -- 21 :> (44 :> (231 :> ())) ---- -- It will be clear that this cannot be reproduced with any combination -- of lenses, Control.Fold folds, or the like. (See also the -- discussion of copy.) -- -- It would conceivably be clearer to import a series of specializations -- of store. It is intended to be used at types like these: -- --
-- storeM :: (forall s m . Monad m => Stream (Of a) m s -> m (Of b s)) -- -> (Monad n => Stream (Of a) n r -> Stream (Of a) n (Of b r)) -- storeM = store -- -- storeMIO :: (forall s m . MonadIO m => Stream (Of a) m s -> m (Of b s)) -- -> (MonadIO n => Stream (Of a) n r -> Stream (Of a) n (Of b r) -- storeMIO = store ---- -- It is clear from these types that we are just using the general -- instances: -- --
-- instance (Functor f, Monad m) => Monad (Stream f m) -- instance (Functor f, MonadIO m) => MonadIO (Stream f m) ---- -- We thus can't be touching the elements of the stream, or the final -- return value. It is the same with other constraints that Stream -- (Of a) inherits from the underlying monad, like -- MonadResource. Thus I can independently filter and write to -- one file, but nub and write to another, or interact with a database -- and a logfile and the like: -- --
-- >>> (S.writeFile "hello2.txt" . S.nubOrd) $ store (S.writeFile "hello.txt" . S.filter (/= "world")) $ each ["hello", "world", "goodbye", "world"] -- -- >>> :! cat hello.txt -- hello -- goodbye -- -- >>> :! cat hello2.txt -- hello -- world -- goodbye --store :: Monad m => (Stream (Of a) (Stream (Of a) m) r -> t) -> Stream (Of a) m r -> t -- | Apply an action to all values, re-yielding each. The return value -- (y) of the function is ignored. -- --
-- >>> S.product $ S.chain Prelude.print $ S.each [1..5] -- 1 -- 2 -- 3 -- 4 -- 5 -- 120 :> () ---- -- See also mapM for a variant of this which uses the return value -- of the function to transorm the values in the stream. chain :: Monad m => (a -> m y) -> Stream (Of a) m r -> Stream (Of a) m r -- | Like the sequence but streaming. The result type is a stream of -- a's, but is not accumulated; the effects of the elements of the -- original stream are interleaved in the resulting stream. Compare: -- --
-- sequence :: Monad m => [m a] -> m [a] -- sequence :: Monad m => Stream (Of (m a)) m r -> Stream (Of a) m r ---- -- This obeys the rule sequence :: Monad m => Stream (Of (m a)) m r -> Stream (Of a) m r -- | Remove repeated elements from a Stream. nubOrd of course -- accumulates a Set of elements that have already been seen and -- should thus be used with care. -- --
-- >>> S.toList_ $ S.nubOrd $ S.take 5 S.readLn :: IO [Int] -- 1<Enter> -- 2<Enter> -- 3<Enter> -- 1<Enter> -- 2<Enter> -- [1,2,3] --nubOrd :: (Monad m, Ord a) => Stream (Of a) m r -> Stream (Of a) m r -- | Use nubOrdOn to have a custom ordering function for your -- elements. nubOrdOn :: (Monad m, Ord b) => (a -> b) -> Stream (Of a) m r -> Stream (Of a) m r -- | More efficient versions of above when working with Ints that -- use IntSet. nubInt :: Monad m => Stream (Of Int) m r -> Stream (Of Int) m r nubIntOn :: Monad m => (a -> Int) -> Stream (Of a) m r -> Stream (Of a) m r -- | Skip elements of a stream that fail a predicate filter :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Of a) m r -- | Skip elements of a stream that fail a monadic test filterM :: Monad m => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m r -- | Map monadically over a stream, producing a new stream only containing -- the Just values. mapMaybeM :: Monad m => (a -> m (Maybe b)) -> Stream (Of a) m r -> Stream (Of b) m r -- | Interpolate a delay of n seconds between yields. delay :: MonadIO m => Double -> Stream (Of a) m r -> Stream (Of a) m r -- | Intersperse given value between each element of the stream. -- --
-- >>> S.print $ S.intersperse 0 $ each [1,2,3] -- 1 -- 0 -- 2 -- 0 -- 3 --intersperse :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) m r -- | End a stream after n elements; the original return value is thus lost. -- splitAt preserves this information. Note that, like -- splitAt, this function is functor-general, so that, for -- example, you can take not just a number of items from a -- stream of elements, but a number of substreams and the like. -- --
-- >>> S.toList $ S.take 3 $ each "with" -- "wit" :> () ---- --
-- >>> S.readFile "stream.hs" (S.stdoutLn . S.take 3) -- import Streaming -- import qualified Streaming.Prelude as S -- import Streaming.Prelude (each, next, yield) --take :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m () -- | End stream when an element fails a condition; the original return -- value is lost. By contrast span preserves this information, and -- is generally more desirable. -- --
-- S.takeWhile thus = void . S.span thus ---- -- To preserve the information - but thus also force the rest of the -- stream to be developed - write -- --
-- S.drained . S.span thus ---- -- as dropWhile thus is -- --
-- S.effects . S.span thus --takeWhile :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Of a) m () -- | Like takeWhile, but takes a monadic predicate. takeWhileM :: Monad m => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m () -- | Ignore the first n elements of a stream, but carry out the actions -- --
-- >>> S.toList $ S.drop 2 $ S.replicateM 5 getLine -- a<Enter> -- b<Enter> -- c<Enter> -- d<Enter> -- e<Enter> -- ["c","d","e"] :> () ---- -- Because it retains the final return value, drop n is a -- suitable argument for maps: -- --
-- >>> S.toList $ concats $ maps (S.drop 4) $ chunksOf 5 $ each [1..20] -- [5,10,15,20] :> () --drop :: Monad m => Int -> Stream (Of a) m r -> Stream (Of a) m r -- | Ignore elements of a stream until a test succeeds, retaining the rest. -- --
-- >>> S.print $ S.dropWhile ((< 5) . length) S.stdinLn -- one<Enter> -- two<Enter> -- three<Enter> -- "three" -- four<Enter> -- "four" -- ^CInterrupted. --dropWhile :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Of a) m r -- | Make a stream of foldable containers into a stream of their separate -- elements. This is just -- --
-- concat str = for str each ---- --
-- >>> S.print $ S.concat (each ["xy","z"]) -- 'x' -- 'y' -- 'z' ---- -- Note that it also has the effect of catMaybes, rights -- map snd and such-like operations. -- --
-- >>> S.print $ S.concat $ S.each [Just 1, Nothing, Just 2]
-- 1
-- 2
--
-- >>> S.print $ S.concat $ S.each [Right 1, Left "Error!", Right 2]
-- 1
-- 2
--
-- >>> S.print $ S.concat $ S.each [('A',1), ('B',2)]
-- 1
-- 2
--
concat :: (Monad m, Foldable f) => Stream (Of (f a)) m r -> Stream (Of a) m r
-- | Strict left scan, streaming, e.g. successive partial results. The seed
-- is yielded first, before any action of finding the next element is
-- performed.
--
-- -- >>> S.print $ S.scan (++) "" id $ each (words "a b c d") -- "" -- "a" -- "ab" -- "abc" -- "abcd" ---- -- scan is fitted for use with Control.Foldl, thus: -- --
-- >>> S.print $ L.purely S.scan L.list $ each [3..5] -- [] -- [3] -- [3,4] -- [3,4,5] --scan :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream (Of a) m r -> Stream (Of b) m r -- | Strict left scan, accepting a monadic function. It can be used with -- FoldMs from Control.Foldl using impurely. -- Here we yield a succession of vectors each recording -- --
-- >>> let v = L.impurely scanM L.vectorM $ each [1..4::Int] :: Stream (Of (Vector Int)) IO () -- -- >>> S.print v -- [] -- [1] -- [1,2] -- [1,2,3] -- [1,2,3,4] --scanM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream (Of a) m r -> Stream (Of b) m r -- | Label each element in a stream with a value accumulated according to a -- fold. -- --
-- >>> S.print $ S.scanned (*) 1 id $ S.each [100,200,300] -- (100,100) -- (200,20000) -- (300,6000000) ---- --
-- >>> S.print $ L.purely S.scanned L.product $ S.each [100,200,300] -- (100,100) -- (200,20000) -- (300,6000000) --scanned :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream (Of a) m r -> Stream (Of (a, b)) m r -- | Make a stream of strings into a stream of parsed values, skipping bad -- cases -- --
-- >>> S.sum_ $ S.read $ S.takeWhile (/= "total") S.stdinLn :: IO Int -- 1000<Enter> -- 2000<Enter> -- total<Enter> -- 3000 --read :: (Monad m, Read a) => Stream (Of String) m r -> Stream (Of a) m r show :: (Monad m, Show a) => Stream (Of a) m r -> Stream (Of String) m r -- | The natural cons for a Stream (Of a). -- --
-- cons a stream = yield a >> stream ---- -- Useful for interoperation: -- --
-- Data.Text.foldr S.cons (return ()) :: Text -> Stream (Of Char) m () -- Lazy.foldrChunks S.cons (return ()) :: Lazy.ByteString -> Stream (Of Strict.ByteString) m () ---- -- and so on. cons :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) m r -- | slidingWindow accumulates the first n elements of a -- stream, update thereafter to form a sliding window of length -- n. It follows the behavior of the slidingWindow function in -- conduit-combinators. -- --
-- >>> S.print $ S.slidingWindow 4 $ S.each "123456" -- fromList "1234" -- fromList "2345" -- fromList "3456" --slidingWindow :: Monad m => Int -> Stream (Of a) m b -> Stream (Of (Seq a)) m b -- | slidingWindowMin finds the minimum in every sliding window of -- n elements of a stream. If within a window there are multiple -- elements that are the least, it prefers the first occurrence (if you -- prefer to have the last occurrence, use the max version and flip your -- comparator). It satisfies: -- --
-- slidingWindowMin n s = map minimum (slidingWindow n s) ---- -- Except that it is far more efficient, especially when the window size -- is large: it calls compare O(m) times overall where -- m is the total number of elements in the stream. slidingWindowMin :: (Monad m, Ord a) => Int -> Stream (Of a) m b -> Stream (Of a) m b -- | slidingWindowMinBy finds the minimum in every sliding window of -- n elements of a stream according to the given comparison -- function (which should define a total ordering). See notes above about -- elements that are equal. It satisfies: -- --
-- slidingWindowMinBy f n s = map (minimumBy f) (slidingWindow n s) ---- -- Except that it is far more efficient, especially when the window size -- is large: it calls the comparison function O(m) times overall -- where m is the total number of elements in the stream. slidingWindowMinBy :: Monad m => (a -> a -> Ordering) -> Int -> Stream (Of a) m b -> Stream (Of a) m b -- | slidingWindowMinOn finds the minimum in every sliding window of -- n elements of a stream according to the given projection -- function. See notes above about elements that are equal. It satisfies: -- --
-- slidingWindowMinOn f n s = map (minimumOn (comparing f)) (slidingWindow n s) ---- -- Except that it is far more efficient, especially when the window size -- is large: it calls compare on the projected value O(m) -- times overall where m is the total number of elements in the -- stream, and it calls the projection function exactly m times. slidingWindowMinOn :: (Monad m, Ord p) => (a -> p) -> Int -> Stream (Of a) m b -> Stream (Of a) m b -- | slidingWindowMax finds the maximum in every sliding window of -- n elements of a stream. If within a window there are multiple -- elements that are the largest, it prefers the last occurrence (if you -- prefer to have the first occurrence, use the min version and flip your -- comparator). It satisfies: -- --
-- slidingWindowMax n s = map maximum (slidingWindow n s) ---- -- Except that it is far more efficient, especially when the window size -- is large: it calls compare O(m) times overall where -- m is the total number of elements in the stream. slidingWindowMax :: (Monad m, Ord a) => Int -> Stream (Of a) m b -> Stream (Of a) m b -- | slidingWindowMaxBy finds the maximum in every sliding window of -- n elements of a stream according to the given comparison -- function (which should define a total ordering). See notes above about -- elements that are equal. It satisfies: -- --
-- slidingWindowMaxBy f n s = map (maximumBy f) (slidingWindow n s) ---- -- Except that it is far more efficient, especially when the window size -- is large: it calls the comparison function O(m) times overall -- where m is the total number of elements in the stream. slidingWindowMaxBy :: Monad m => (a -> a -> Ordering) -> Int -> Stream (Of a) m b -> Stream (Of a) m b -- | slidingWindowMaxOn finds the maximum in every sliding window of -- n elements of a stream according to the given projection -- function. See notes above about elements that are equal. It satisfies: -- --
-- slidingWindowMaxOn f n s = map (maximumOn (comparing f)) (slidingWindow n s) ---- -- Except that it is far more efficient, especially when the window size -- is large: it calls compare on the projected value O(m) -- times overall where m is the total number of elements in the -- stream, and it calls the projection function exactly m times. slidingWindowMaxOn :: (Monad m, Ord p) => (a -> p) -> Int -> Stream (Of a) m b -> Stream (Of a) m b -- | Before evaluating the monadic action returning the next step in the -- Stream, wrapEffect extracts the value in a monadic -- computation m a and passes it to a computation a -> m -- y. wrapEffect :: (Monad m, Functor f) => m a -> (a -> m y) -> Stream f m r -> Stream f m r -- | The standard way of inspecting the first item in a stream of elements, -- if the stream is still 'running'. The Right case contains a -- Haskell pair, where the more general inspect would return a -- left-strict pair. There is no reason to prefer inspect since, -- if the Right case is exposed, the first element in the pair -- will have been evaluated to whnf. -- --
-- next :: Monad m => Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r)) -- inspect :: Monad m => Stream (Of a) m r -> m (Either r (Of a (Stream (Of a) m r))) ---- -- Interoperate with pipes producers thus: -- --
-- Pipes.unfoldr Stream.next :: Stream (Of a) m r -> Producer a m r -- Stream.unfoldr Pipes.next :: Producer a m r -> Stream (Of a) m r ---- -- Similarly: -- --
-- IOStreams.unfoldM (fmap (either (const Nothing) Just) . next) :: Stream (Of a) IO b -> IO (InputStream a) -- Conduit.unfoldM (fmap (either (const Nothing) Just) . next) :: Stream (Of a) m r -> Source a m r ---- -- But see uncons, which is better fitted to these -- unfoldMs next :: Monad m => Stream (Of a) m r -> m (Either r (a, Stream (Of a) m r)) -- | Inspect the first item in a stream of elements, without a return -- value. uncons provides convenient exit into another streaming -- type: -- --
-- IOStreams.unfoldM uncons :: Stream (Of a) IO b -> IO (InputStream a) -- Conduit.unfoldM uncons :: Stream (Of a) m r -> Conduit.Source m a --uncons :: Monad m => Stream (Of a) m r -> m (Maybe (a, Stream (Of a) m r)) -- | Split a succession of layers after some number, returning a streaming -- or effectful pair. This function is the same as the splitsAt -- exported by the Streaming module, but since this module is -- imported qualified, it can usurp a Prelude name. It specializes to: -- --
-- splitAt :: (Monad m) => Int -> Stream (Of a) m r -> Stream (Of a) m (Stream (Of a) m r) --splitAt :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Stream f m r) -- | Split a stream of elements wherever a given element arises. The action -- is like that of words. -- --
-- >>> S.stdoutLn $ mapped S.toList $ S.split ' ' $ each "hello world " -- hello -- world --split :: (Eq a, Monad m) => a -> Stream (Of a) m r -> Stream (Stream (Of a) m) m r -- | Break during periods where the predicate is not satisfied, grouping -- the periods when it is. -- --
-- >>> S.print $ mapped S.toList $ S.breaks not $ S.each [False,True,True,False,True,True,False] -- [True,True] -- [True,True] -- -- >>> S.print $ mapped S.toList $ S.breaks id $ S.each [False,True,True,False,True,True,False] -- [False] -- [False] -- [False] --breaks :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Stream (Of a) m) m r -- | Break a sequence upon meeting element falls under a predicate, keeping -- it and the rest of the stream as the return value. -- --
-- >>> rest <- S.print $ S.break even $ each [1,1,2,3] -- 1 -- 1 -- -- >>> S.print rest -- 2 -- 3 --break :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Of a) m (Stream (Of a) m r) -- | Yield elements, using a fold to maintain state, until the accumulated -- value satifies the supplied predicate. The fold will then be -- short-circuited and the element that breaks it will be put after the -- break. This function is easiest to use with purely -- --
-- >>> rest <- each [1..10] & L.purely S.breakWhen L.sum (>10) & S.print -- 1 -- 2 -- 3 -- 4 -- -- >>> S.print rest -- 5 -- 6 -- 7 -- 8 -- 9 -- 10 --breakWhen :: Monad m => (x -> a -> x) -> x -> (x -> b) -> (b -> Bool) -> Stream (Of a) m r -> Stream (Of a) m (Stream (Of a) m r) -- | Stream elements until one fails the condition, return the rest. span :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Of a) m (Stream (Of a) m r) -- | Group successive equal items together -- --
-- >>> S.toList $ mapped S.toList $ S.group $ each "baaaaad" -- ["b","aaaaa","d"] :> () ---- --
-- >>> S.toList $ concats $ maps (S.drained . S.splitAt 1) $ S.group $ each "baaaaaaad" -- "bad" :> () --group :: (Monad m, Eq a) => Stream (Of a) m r -> Stream (Stream (Of a) m) m r -- | Group elements of a stream in accordance with the supplied comparison. -- --
-- >>> S.print $ mapped S.toList $ S.groupBy (>=) $ each [1,2,3,1,2,3,4,3,2,4,5,6,7,6,5] -- [1] -- [2] -- [3,1,2,3] -- [4,3,2,4] -- [5] -- [6] -- [7,6,5] --groupBy :: Monad m => (a -> a -> Bool) -> Stream (Of a) m r -> Stream (Stream (Of a) m) m r distinguish :: (a -> Bool) -> Of a r -> Sum (Of a) (Of a) r -- | Swap the order of functors in a sum of functors. -- --
-- >>> S.toList $ S.print $ separate $ maps S.switch $ maps (S.distinguish (=='a')) $ S.each "banana" -- 'a' -- 'a' -- 'a' -- "bnn" :> () -- -- >>> S.toList $ S.print $ separate $ maps (S.distinguish (=='a')) $ S.each "banana" -- 'b' -- 'n' -- 'n' -- "aaa" :> () --switch :: Sum f g r -> Sum g f r -- | Given a stream on a sum of functors, make it a stream on the left -- functor, with the streaming on the other functor as the governing -- monad. This is useful for acting on one or the other functor with a -- fold, leaving the other material for another treatment. It generalizes -- partitionEithers, but actually streams properly. -- --
-- >>> let odd_even = S.maps (S.distinguish even) $ S.each [1..10::Int] -- -- >>> :t separate odd_even -- separate odd_even -- :: Monad m => Stream (Of Int) (Stream (Of Int) m) () ---- -- Now, for example, it is convenient to fold on the left and right -- values separately: -- --
-- >>> S.toList $ S.toList $ separate odd_even -- [2,4,6,8,10] :> ([1,3,5,7,9] :> ()) ---- -- Or we can write them to separate files or whatever: -- --
-- >>> S.writeFile "even.txt" . S.show $ S.writeFile "odd.txt" . S.show $ S.separate odd_even -- -- >>> :! cat even.txt -- 2 -- 4 -- 6 -- 8 -- 10 -- -- >>> :! cat odd.txt -- 1 -- 3 -- 5 -- 7 -- 9 ---- -- Of course, in the special case of Stream (Of a) m r, we can -- achieve the above effects more simply by using copy -- --
-- >>> S.toList . S.filter even $ S.toList . S.filter odd $ S.copy $ each [1..10::Int] -- [2,4,6,8,10] :> ([1,3,5,7,9] :> ()) ---- -- But separate and unseparate are functor-general. separate :: (Monad m, Functor f, Functor g) => Stream (Sum f g) m r -> Stream f (Stream g m) r unseparate :: (Monad m, Functor f, Functor g) => Stream f (Stream g m) r -> Stream (Sum f g) m r eitherToSum :: Of (Either a b) r -> Sum (Of a) (Of b) r sumToEither :: Sum (Of a) (Of b) r -> Of (Either a b) r sumToCompose :: Sum f f r -> Compose (Of Bool) f r composeToSum :: Compose (Of Bool) f r -> Sum f f r -- | Strict fold of a Stream of elements that preserves the return -- value. The third parameter will often be id where a fold is -- written by hand: -- --
-- >>> S.fold (+) 0 id $ each [1..10] -- 55 :> () ---- --
-- >>> S.fold (*) 1 id $ S.fold (+) 0 id $ S.copy $ each [1..10] -- 3628800 :> (55 :> ()) ---- -- It can be used to replace a standard Haskell type with one more suited -- to writing a strict accumulation function. It is also crucial to the -- Applicative instance for Control.Foldl.Fold We can apply such -- a fold purely -- --
-- Control.Foldl.purely S.fold :: Monad m => Fold a b -> Stream (Of a) m r -> m (Of b r) ---- -- Thus, specializing a bit: -- --
-- L.purely S.fold L.sum :: Stream (Of Int) Int r -> m (Of Int r) -- mapped (L.purely S.fold L.sum) :: Stream (Stream (Of Int)) IO r -> Stream (Of Int) IO r ---- -- Here we use the Applicative instance for Control.Foldl.Fold -- to stream three-item segments of a stream together with their sums and -- products. -- --
-- >>> S.print $ mapped (L.purely S.fold (liftA3 (,,) L.list L.product L.sum)) $ chunksOf 3 $ each [1..10] -- ([1,2,3],6,6) -- ([4,5,6],120,15) -- ([7,8,9],504,24) -- ([10],10,10) --fold :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream (Of a) m r -> m (Of b r) -- | Strict fold of a Stream of elements, preserving only the result -- of the fold, not the return value of the stream. The third parameter -- will often be id where a fold is written by hand: -- --
-- >>> S.fold_ (+) 0 id $ each [1..10] -- 55 ---- -- It can be used to replace a standard Haskell type with one more suited -- to writing a strict accumulation function. It is also crucial to the -- Applicative instance for Control.Foldl.Fold -- --
-- Control.Foldl.purely fold :: Monad m => Fold a b -> Stream (Of a) m () -> m b --fold_ :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream (Of a) m r -> m b -- | Strict, monadic fold of the elements of a Stream (Of a) -- --
-- Control.Foldl.impurely foldM' :: Monad m => FoldM a b -> Stream (Of a) m r -> m (b, r) ---- -- Thus to accumulate the elements of a stream as a vector, together with -- a random element we might write: -- --
-- >>> L.impurely S.foldM (liftA2 (,) L.vectorM L.random) $ each [1..10::Int] :: IO (Of (Vector Int, Maybe Int) ()) -- ([1,2,3,4,5,6,7,8,9,10],Just 9) :> () --foldM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream (Of a) m r -> m (Of b r) -- | Strict, monadic fold of the elements of a Stream (Of a) -- --
-- Control.Foldl.impurely foldM :: Monad m => FoldM a b -> Stream (Of a) m () -> m b --foldM_ :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream (Of a) m r -> m b -- | Map each element of the stream to a monoid, and take the monoidal sum -- of the results. -- --
-- >>> S.foldMap Sum $ S.take 2 (S.stdinLn)
-- 1<Enter>
-- 2<Enter>
-- 3<Enter>
-- Sum {getSum = 6} :> ()
--
foldMap :: (Monad m, Monoid w) => (a -> w) -> Stream (Of a) m r -> m (Of w r)
foldMap_ :: (Monad m, Monoid w) => (a -> w) -> Stream (Of a) m r -> m w
all :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m (Of Bool r)
all_ :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m Bool
any :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m (Of Bool r)
any_ :: Monad m => (a -> Bool) -> Stream (Of a) m r -> m Bool
-- | Fold a Stream of numbers into their sum with the return value
--
-- -- mapped S.sum :: Stream (Stream (Of Int)) m r -> Stream (Of Int) m r ---- --
-- >>> S.sum $ each [1..10] -- 55 :> () ---- --
-- >>> (n :> rest) <- S.sum $ S.splitAt 3 $ each [1..10] -- -- >>> System.IO.print n -- 6 -- -- >>> (m :> rest') <- S.sum $ S.splitAt 3 rest -- -- >>> System.IO.print m -- 15 -- -- >>> S.print rest' -- 7 -- 8 -- 9 -- 10 --sum :: (Monad m, Num a) => Stream (Of a) m r -> m (Of a r) -- | Fold a Stream of numbers into their sum sum_ :: (Monad m, Num a) => Stream (Of a) m () -> m a -- | Fold a Stream of numbers into their product with the return -- value -- --
-- mapped product :: Stream (Stream (Of Int)) m r -> Stream (Of Int) m r --product :: (Monad m, Num a) => Stream (Of a) m r -> m (Of a r) -- | Fold a Stream of numbers into their product product_ :: (Monad m, Num a) => Stream (Of a) m () -> m a head :: Monad m => Stream (Of a) m r -> m (Of (Maybe a) r) head_ :: Monad m => Stream (Of a) m r -> m (Maybe a) last :: Monad m => Stream (Of a) m r -> m (Of (Maybe a) r) last_ :: Monad m => Stream (Of a) m r -> m (Maybe a) -- | Exhaust a stream remembering only whether a was an element. elem :: (Monad m, Eq a) => a -> Stream (Of a) m r -> m (Of Bool r) elem_ :: (Monad m, Eq a) => a -> Stream (Of a) m r -> m Bool -- | Exhaust a stream deciding whether a was an element. notElem :: (Monad m, Eq a) => a -> Stream (Of a) m r -> m (Of Bool r) notElem_ :: (Monad m, Eq a) => a -> Stream (Of a) m r -> m Bool -- | Run a stream, keeping its length and its return value. -- --
-- >>> S.print $ mapped S.length $ chunksOf 3 $ S.each [1..10] -- 3 -- 3 -- 3 -- 1 --length :: Monad m => Stream (Of a) m r -> m (Of Int r) -- | Run a stream, remembering only its length: -- --
-- >>> runIdentity $ S.length_ (S.each [1..10] :: Stream (Of Int) Identity ()) -- 10 --length_ :: Monad m => Stream (Of a) m r -> m Int -- | Convert an effectful Stream into a list alongside the return -- value -- --
-- mapped toList :: Stream (Stream (Of a) m) m r -> Stream (Of [a]) m r ---- -- Like toList_, toList breaks streaming; unlike -- toList_ it preserves the return value and thus is -- frequently useful with e.g. mapped -- --
-- >>> S.print $ mapped S.toList $ chunksOf 3 $ each [1..9] -- [1,2,3] -- [4,5,6] -- [7,8,9] ---- --
-- >>> S.print $ mapped S.toList $ chunksOf 2 $ S.replicateM 4 getLine -- s<Enter> -- t<Enter> -- ["s","t"] -- u<Enter> -- v<Enter> -- ["u","v"] --toList :: Monad m => Stream (Of a) m r -> m (Of [a] r) -- | Convert an effectful Stream (Of a) into a list of as -- -- Note: Needless to say, this function does not stream properly. It is -- basically the same as Prelude mapM which, like -- replicateM, sequence and similar operations on -- traversable containers is a leading cause of space leaks. toList_ :: Monad m => Stream (Of a) m r -> m [a] -- | Fold streamed items into their monoidal sum -- --
-- >>> S.mconcat $ S.take 2 $ S.map (Data.Monoid.Last . Just) S.stdinLn
-- first<Enter>
-- last<Enter>
-- Last {getLast = Just "last"} :> ()
--
mconcat :: (Monad m, Monoid w) => Stream (Of w) m r -> m (Of w r)
mconcat_ :: (Monad m, Monoid w) => Stream (Of w) m r -> m w
minimum :: (Monad m, Ord a) => Stream (Of a) m r -> m (Of (Maybe a) r)
minimum_ :: (Monad m, Ord a) => Stream (Of a) m r -> m (Maybe a)
maximum :: (Monad m, Ord a) => Stream (Of a) m r -> m (Of (Maybe a) r)
maximum_ :: (Monad m, Ord a) => Stream (Of a) m r -> m (Maybe a)
-- | A natural right fold for consuming a stream of elements. See also the
-- more general iterT in the Streaming module and the
-- still more general destroy
foldrM :: Monad m => (a -> m r -> m r) -> Stream (Of a) m r -> m r
-- | A natural right fold for consuming a stream of elements. See also the
-- more general iterTM in the Streaming module and the
-- still more general destroy
--
-- -- foldrT (\a p -> Streaming.yield a >> p) = id -- foldrT (\a p -> Pipes.yield a >> p) :: Monad m => Stream (Of a) m r -> Producer a m r -- foldrT (\a p -> Conduit.yield a >> p) :: Monad m => Stream (Of a) m r -> Conduit a m r --foldrT :: (Monad m, MonadTrans t, Monad (t m)) => (a -> t m r -> t m r) -> Stream (Of a) m r -> t m r -- | Zip two Streams zip :: Monad m => Stream (Of a) m r -> Stream (Of b) m r -> Stream (Of (a, b)) m r -- | Zip two Streams using the provided combining function zipWith :: Monad m => (a -> b -> c) -> Stream (Of a) m r -> Stream (Of b) m r -> Stream (Of c) m r -- | Zip three Streams together zip3 :: Monad m => Stream (Of a) m r -> Stream (Of b) m r -> Stream (Of c) m r -> Stream (Of (a, b, c)) m r -- | Zip three Streams with a combining function zipWith3 :: Monad m => (a -> b -> c -> d) -> Stream (Of a) m r -> Stream (Of b) m r -> Stream (Of c) m r -> Stream (Of d) m r -- | The type -- --
-- Data.List.unzip :: [(a,b)] -> ([a],[b]) ---- -- might lead us to expect -- --
-- Streaming.unzip :: Stream (Of (a,b)) m r -> Stream (Of a) m (Stream (Of b) m r) ---- -- which would not stream, since it would have to accumulate the second -- stream (of bs). Of course, Data.List unzip -- doesn't stream either. -- -- This unzip does stream, though of course you can spoil this -- by using e.g. toList: -- --
-- >>> let xs = Prelude.map (\x -> (x, Prelude.show x)) [1..5 :: Int] ---- --
-- >>> S.toList $ S.toList $ S.unzip (S.each xs) -- ["1","2","3","4","5"] :> ([1,2,3,4,5] :> ()) ---- --
-- >>> Prelude.unzip xs -- ([1,2,3,4,5],["1","2","3","4","5"]) ---- -- Note the difference of order in the results. It may be of some use to -- think why. The first application of toList was applied to a -- stream of integers: -- --
-- >>> :t S.unzip $ S.each xs -- S.unzip $ S.each xs :: Monad m => Stream (Of Int) (Stream (Of String) m) () ---- -- Like any fold, toList takes no notice of the monad of effects. -- --
-- toList :: Monad m => Stream (Of a) m r -> m (Of [a] r) ---- -- In the case at hand (since I am in ghci) m = Stream (Of -- String) IO. So when I apply toList, I exhaust that stream -- of integers, folding it into a list: -- --
-- >>> :t S.toList $ S.unzip $ S.each xs -- S.toList $ S.unzip $ S.each xs -- :: Monad m => Stream (Of String) m (Of [Int] ()) ---- -- When I apply toList to this, I reduce everything to an -- ordinary action in IO, and return a list of strings: -- --
-- >>> S.toList $ S.toList $ S.unzip (S.each xs) -- ["1","2","3","4","5"] :> ([1,2,3,4,5] :> ()) ---- -- unzip can be considered a special case of either unzips -- or expand: -- --
-- unzip = unzips . maps (\((a,b) :> x) -> Compose (a :> b :> x)) -- unzip = expand $ \p ((a,b) :> abs) -> b :> p (a :> abs) --unzip :: Monad m => Stream (Of (a, b)) m r -> Stream (Of a) (Stream (Of b) m) r -- | Separate left and right values in distinct streams. (separate -- is a more powerful, functor-general, equivalent using Sum in -- place of Either). So, for example, to permit unlimited user -- input of Ints on condition of only two errors, we might -- write: -- --
-- >>> S.toList $ S.print $ S.take 2 $ partitionEithers $ S.map readEither $ S.stdinLn :: IO (Of [Int] ()) -- 1<Enter> -- 2<Enter> -- qqqqqqqqqq<Enter> -- "Prelude.read: no parse" -- 3<Enter> -- rrrrrrrrrr<Enter> -- "Prelude.read: no parse" -- [1,2,3] :> () ---- --
-- partitionEithers = separate . maps S.eitherToSum -- lefts = hoist S.effects . partitionEithers -- rights = S.effects . partitionEithers -- rights = S.concat --partitionEithers :: Monad m => Stream (Of (Either a b)) m r -> Stream (Of a) (Stream (Of b) m) r -- |
-- filter p = hoist effects (partition p) --partition :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Of a) (Stream (Of a) m) r -- | Merge two streams of elements ordered with their Ord instance. -- -- The return values of both streams are returned. -- --
-- >>> S.print $ merge (each [1,3,5]) (each [2,4]) -- 1 -- 2 -- 3 -- 4 -- 5 -- ((), ()) --merge :: (Monad m, Ord a) => Stream (Of a) m r -> Stream (Of a) m s -> Stream (Of a) m (r, s) -- | Merge two streams, ordering them by applying the given function to -- each element before comparing. -- -- The return values of both streams are returned. mergeOn :: (Monad m, Ord b) => (a -> b) -> Stream (Of a) m r -> Stream (Of a) m s -> Stream (Of a) m (r, s) -- | Merge two streams, ordering the elements using the given comparison -- function. -- -- The return values of both streams are returned. mergeBy :: Monad m => (a -> a -> Ordering) -> Stream (Of a) m r -> Stream (Of a) m s -> Stream (Of a) m (r, s) -- | The catMaybes function takes a Stream of Maybes -- and returns a Stream of all of the Just values. -- concat has the same behavior, but is more general; it works for -- any foldable container type. catMaybes :: Monad m => Stream (Of (Maybe a)) m r -> Stream (Of a) m r -- | The mapMaybe function is a version of map which can -- throw out elements. In particular, the functional argument returns -- something of type Maybe b. If this is Nothing, -- no element is added on to the result Stream. If it is -- Just b, then b is included in the result -- Stream. mapMaybe :: Monad m => (a -> Maybe b) -> Stream (Of a) m r -> Stream (Of b) m r -- | 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 can restate some types as follows: -- --
-- mapOf :: (a -> b) -> Of a ~~> Of b -- Bifunctor first -- lazily :: Of a ~~> (,) a -- Identity . fst' :: Of a ~~> Identity a ---- -- Manipulation of a Stream f m r by mapping often turns on -- recognizing natural transformations of f. Thus maps -- is far more general the the map of the -- Streaming.Prelude, which can be defined thus: -- --
-- S.map :: (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r -- S.map f = maps (mapOf f) ---- -- i.e. -- --
-- S.map f = maps (\(a :> x) -> (f a :> x)) ---- -- 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 ---- -- Thus we can maps it in turn. lazily :: Of a b -> (a, b) -- | Convert a standard Haskell pair into a left-strict pair strictly :: (a, b) -> Of a b -- | fst' and snd' extract the first and second element -- of a pair -- --
-- >>> S.fst' (1:>"hi") -- 1 -- -- >>> S.snd' (1:>"hi") -- "hi" ---- -- They are contained in the _first and _second lenses, -- if any lens library is in scope -- --
-- >>> import Lens.Micro -- -- >>> (1:>"hi") ^. S._first -- 1 -- -- >>> (1:>"hi") ^. S._second -- "hi" --fst' :: Of a b -> a snd' :: Of a b -> b -- | Map a function over the first element of an Of pair -- --
-- >>> S.mapOf even (1:>"hi") -- False :> "hi" ---- -- mapOf is just first from the Bifunctor -- instance -- --
-- >>> first even (1:>"hi") -- False :> "hi" ---- -- and is contained in the _first lens -- --
-- >>> import Lens.Micro -- -- >>> over S._first even (1:>"hi") -- False :> "hi" --mapOf :: (a -> b) -> Of a r -> Of b r -- | A lens into the first element of a left-strict pair _first :: Functor f => (a -> f a') -> Of a b -> f (Of a' b) -- | A lens into the second element of a left-strict pair _second :: Functor f => (b -> f b') -> Of a b -> f (Of a b') -- | Read an IORef (Maybe a) or a similar device until it reads -- Nothing. reread provides convenient exit from the -- io-streams library -- --
-- reread readIORef :: IORef (Maybe a) -> Stream (Of a) IO () -- reread Streams.read :: System.IO.Streams.InputStream a -> Stream (Of a) IO () --reread :: Monad m => (s -> m (Maybe a)) -> s -> Stream (Of a) m () data Stream f m r module Streaming data Stream f m r -- | yields is like lift for items in the streamed -- functor. It makes a singleton or one-layer succession. -- --
-- lift :: (Monad m, Functor f) => m r -> Stream f m r -- yields :: (Monad m, Functor f) => f r -> Stream f m r ---- -- Viewed in another light, it is like a functor-general version of -- yield: -- --
-- S.yield a = yields (a :> ()) --yields :: (Monad m, Functor f) => f r -> Stream f m r -- | Wrap an effect that returns a stream -- --
-- effect = join . lift --effect :: (Monad m, Functor f) => m (Stream f m r) -> Stream f m r -- | Wrap a new layer of a stream. So, e.g. -- --
-- S.cons :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) m r -- S.cons a str = wrap (a :> str) ---- -- and, recursively: -- --
-- S.each :: (Monad m, Foldable t) => t a -> Stream (Of a) m () -- S.each = foldr (\a b -> wrap (a :> b)) (return ()) ---- -- The two operations -- --
-- wrap :: (Monad m, Functor f ) => f (Stream f m r) -> Stream f m r -- effect :: (Monad m, Functor f ) => m (Stream f m r) -> Stream f m r ---- -- are fundamental. We can define the parallel operations yields -- and lift in terms of them -- --
-- yields :: (Monad m, Functor f ) => f r -> Stream f m r -- yields = wrap . fmap return -- lift :: (Monad m, Functor f ) => m r -> Stream f m r -- lift = effect . fmap return --wrap :: (Monad m, Functor f) => f (Stream f m r) -> Stream f m r -- | Repeat a functorial layer, command or instruction a fixed number of -- times. -- --
-- replicates n = takes n . repeats --replicates :: (Monad m, Functor f) => Int -> f () -> Stream f m () -- | Repeat a functorial layer (a "command" or "instruction") forever. repeats :: (Monad m, Functor f) => f () -> Stream f m r -- | Repeat an effect containing a functorial layer, command or instruction -- forever. repeatsM :: (Monad m, Functor f) => m (f ()) -> Stream f m r -- | Build a Stream by unfolding steps starting from a seed. See -- also the specialized unfoldr in the prelude. -- --
-- unfold inspect = id -- modulo the quotient we work with -- unfold Pipes.next :: Monad m => Producer a m r -> Stream ((,) a) m r -- unfold (curry (:>) . Pipes.next) :: Monad m => Producer a m r -> Stream (Of a) m r --unfold :: (Monad m, Functor f) => (s -> m (Either r (f s))) -> s -> Stream f m r -- | never interleaves the pure applicative action with the return -- of the monad forever. It is the empty of the Alternative -- instance, thus -- --
-- never <|> a = a -- a <|> never = a ---- -- and so on. If w is a monoid then never :: Stream (Of w) m r -- is the infinite sequence of mempty, and str1 <|> -- str2 appends the elements monoidally until one of streams ends. -- Thus we have, e.g. -- --
-- >>> S.stdoutLn $ S.take 2 $ S.stdinLn <|> S.repeat " " <|> S.stdinLn <|> S.repeat " " <|> S.stdinLn -- 1<Enter> -- 2<Enter> -- 3<Enter> -- 1 2 3 -- 4<Enter> -- 5<Enter> -- 6<Enter> -- 4 5 6 ---- -- This is equivalent to -- --
-- >>> S.stdoutLn $ S.take 2 $ foldr (<|>) never [S.stdinLn, S.repeat " ", S.stdinLn, S.repeat " ", S.stdinLn ] ---- -- Where f is a monad, (<|>) sequences the -- conjoined streams stepwise. See the definition of paste -- here, where the separate steps are bytestreams corresponding to -- the lines of a file. -- -- Given, say, -- --
-- data Branch r = Branch r r deriving Functor -- add obvious applicative instance ---- -- then never :: Stream Branch Identity r is the pure infinite -- binary tree with (inaccessible) rs in its leaves. Given two -- binary trees, tree1 <|> tree2 intersects them, -- preserving the leaves that came first, so tree1 <|> never = -- tree1 -- -- Stream Identity m r is an action in m that is -- indefinitely delayed. Such an action can be constructed with e.g. -- untilJust. -- --
-- untilJust :: (Monad m, Applicative f) => m (Maybe r) -> Stream f m r ---- -- Given two such items, <|> instance races them. It is -- thus the iterative monad transformer specially defined in -- Control.Monad.Trans.Iter -- -- So, for example, we might write -- --
-- >>> let justFour str = if length str == 4 then Just str else Nothing -- -- >>> let four = untilJust (fmap justFour getLine) -- -- >>> run four -- one<Enter> -- two<Enter> -- three<Enter> -- four<Enter> -- "four" ---- -- The Alternative instance in Control.Monad.Trans.Free is -- avowedly wrong, though no explanation is given for this. never :: (Monad m, Applicative f) => Stream f m r -- | Repeat a untilJust :: (Monad m, Applicative f) => m (Maybe r) -> Stream f m r -- | Reflect a church-encoded stream; cp. GHC.Exts.build -- --
-- streamFold return_ effect_ step_ (streamBuild psi) = psi return_ effect_ step_ --streamBuild :: (forall b. (r -> b) -> (m b -> b) -> (f b -> b) -> b) -> Stream f m r delays :: (MonadIO m, Applicative f) => Double -> Stream f m r -- | Map layers of one functor to another with a transformation. Compare -- hoist, which has a similar effect on the monadic parameter. -- --
-- maps id = id -- maps f . maps g = maps (f . g) --maps :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation. Compare -- hoist, which has a similar effect on the monadic parameter. -- --
-- mapsPost id = id -- mapsPost f . mapsPost g = mapsPost (f . g) -- mapsPost f = maps f ---- -- mapsPost is essentially the same as maps, but it -- imposes a Functor constraint on its target functor rather than -- its source functor. It should be preferred if fmap is cheaper -- for the target functor than for the source functor. mapsPost :: forall m f g r. (Monad m, Functor g) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation involving -- the base monad. maps is more fundamental than mapsM, -- which is best understood as a convenience for effecting this frequent -- composition: -- --
-- mapsM phi = decompose . maps (Compose . phi) ---- -- The streaming prelude exports the same function under the better name -- mapped, which overlaps with the lens libraries. mapsM :: (Monad m, Functor f) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation involving -- the base monad. mapsMPost is essentially the same as -- mapsM, but it imposes a Functor constraint on its target -- functor rather than its source functor. It should be preferred if -- fmap is cheaper for the target functor than for the source -- functor. -- -- mapsPost is more fundamental than mapsMPost, which -- is best understood as a convenience for effecting this frequent -- composition: -- --
-- mapsMPost phi = decompose . mapsPost (Compose . phi) ---- -- The streaming prelude exports the same function under the better name -- mappedPost, which overlaps with the lens libraries. mapsMPost :: forall m f g r. (Monad m, Functor g) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | Map layers of one functor to another with a transformation involving -- the base monad. -- -- This function is completely functor-general. It is often useful with -- the more concrete type -- --
-- mapped :: (forall x. Stream (Of a) IO x -> IO (Of b x)) -> Stream (Stream (Of a) IO) IO r -> Stream (Of b) IO r ---- -- to process groups which have been demarcated in an effectful, -- IO-based stream by grouping functions like group, -- split or breaks. Summary functions like fold, -- foldM, mconcat or toList are often used to define -- the transformation argument. For example: -- --
-- >>> S.toList_ $ S.mapped S.toList $ S.split 'c' (S.each "abcde") -- ["ab","de"] ---- -- maps and mapped obey these rules: -- --
-- maps id = id -- mapped return = id -- maps f . maps g = maps (f . g) -- mapped f . mapped g = mapped (f <=< g) -- maps f . mapped g = mapped (fmap f . g) -- mapped f . maps g = mapped (f <=< fmap g) ---- -- maps is more fundamental than mapped, which is best -- understood as a convenience for effecting this frequent composition: -- --
-- mapped phi = decompose . maps (Compose . phi) --mapped :: (Monad m, Functor f) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | A version of mapped that imposes a Functor constraint on -- the target functor rather than the source functor. This version should -- be preferred if fmap on the target functor is cheaper. mappedPost :: (Monad m, Functor g) => (forall x. f x -> m (g x)) -> Stream f m r -> Stream g m r -- | A less-efficient version of hoist that works properly even when -- its argument is not a monad morphism. -- --
-- hoistUnexposed = hoist . unexposed --hoistUnexposed :: (Monad m, Functor f) => (forall a. m a -> n a) -> Stream f m r -> Stream f n r -- | Make it possible to 'run' the underlying transformed monad. distribute :: (Monad m, Functor f, MonadTrans t, MFunctor t, Monad (t (Stream f m))) => Stream f (t m) r -> t (Stream f m) r -- | Group layers in an alternating stream into adjoining sub-streams of -- one type or another. groups :: (Monad m, Functor f, Functor g) => Stream (Sum f g) m r -> Stream (Sum (Stream f m) (Stream g m)) m r -- | Inspect the first stage of a freely layered sequence. Compare -- Pipes.next and the replica Streaming.Prelude.next. -- This is the uncons for the general unfold. -- --
-- unfold inspect = id -- Streaming.Prelude.unfoldr StreamingPrelude.next = id --inspect :: Monad m => Stream f m r -> m (Either r (f (Stream f m r))) -- | Split a succession of layers after some number, returning a streaming -- or effectful pair. -- --
-- >>> rest <- S.print $ S.splitAt 1 $ each [1..3] -- 1 -- -- >>> S.print rest -- 2 -- 3 ---- --
-- splitAt 0 = return -- splitAt n >=> splitAt m = splitAt (m+n) ---- -- Thus, e.g. -- --
-- >>> rest <- S.print $ splitsAt 2 >=> splitsAt 2 $ each [1..5] -- 1 -- 2 -- 3 -- 4 -- -- >>> S.print rest -- 5 --splitsAt :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Stream f m r) takes :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m () -- | Break a stream into substreams each with n functorial layers. -- --
-- >>> S.print $ mapped S.sum $ chunksOf 2 $ each [1,1,1,1,1] -- 2 -- 2 -- 1 --chunksOf :: (Monad m, Functor f) => Int -> Stream f m r -> Stream (Stream f m) m r -- | Dissolves the segmentation into layers of Stream f m layers. concats :: (Monad m, Functor f) => Stream (Stream f m) m r -> Stream f m r -- | Interpolate a layer at each segment. This specializes to e.g. -- --
-- intercalates :: (Monad m, Functor f) => Stream f m () -> Stream (Stream f m) m r -> Stream f m r --intercalates :: (Monad m, Monad (t m), MonadTrans t) => t m x -> Stream (t m) m r -> t m r cutoff :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m (Maybe r) -- | Zip two streams together. The zipsWith' function should -- generally be preferred for efficiency. zipsWith :: forall f g h m r. (Monad m, Functor h) => (forall x y. f x -> g y -> h (x, y)) -> Stream f m r -> Stream g m r -> Stream h m r -- | Zip two streams together. zipsWith' :: forall f g h m r. Monad m => (forall x y p. (x -> y -> p) -> f x -> g y -> h p) -> Stream f m r -> Stream g m r -> Stream h m r zips :: (Monad m, Functor f, Functor g) => Stream f m r -> Stream g m r -> Stream (Compose f g) m r unzips :: (Monad m, Functor f, Functor g) => Stream (Compose f g) m r -> Stream f (Stream g m) r -- | Interleave functor layers, with the effects of the first preceding the -- effects of the second. When the first stream runs out, any remaining -- effects in the second are ignored. -- --
-- interleaves = zipsWith (liftA2 (,)) ---- --
-- >>> let paste = \a b -> interleaves (Q.lines a) (maps (Q.cons' '\t') (Q.lines b)) -- -- >>> Q.stdout $ Q.unlines $ paste "hello\nworld\n" "goodbye\nworld\n" -- hello goodbye -- world world --interleaves :: (Monad m, Applicative h) => Stream h m r -> Stream h m r -> Stream h m r -- | Given a stream on a sum of functors, make it a stream on the left -- functor, with the streaming on the other functor as the governing -- monad. This is useful for acting on one or the other functor with a -- fold, leaving the other material for another treatment. It generalizes -- partitionEithers, but actually streams properly. -- --
-- >>> let odd_even = S.maps (S.distinguish even) $ S.each [1..10::Int] -- -- >>> :t separate odd_even -- separate odd_even -- :: Monad m => Stream (Of Int) (Stream (Of Int) m) () ---- -- Now, for example, it is convenient to fold on the left and right -- values separately: -- --
-- >>> S.toList $ S.toList $ separate odd_even -- [2,4,6,8,10] :> ([1,3,5,7,9] :> ()) ---- -- Or we can write them to separate files or whatever: -- --
-- >>> S.writeFile "even.txt" . S.show $ S.writeFile "odd.txt" . S.show $ S.separate odd_even -- -- >>> :! cat even.txt -- 2 -- 4 -- 6 -- 8 -- 10 -- -- >>> :! cat odd.txt -- 1 -- 3 -- 5 -- 7 -- 9 ---- -- Of course, in the special case of Stream (Of a) m r, we can -- achieve the above effects more simply by using copy -- --
-- >>> S.toList . S.filter even $ S.toList . S.filter odd $ S.copy $ each [1..10::Int] -- [2,4,6,8,10] :> ([1,3,5,7,9] :> ()) ---- -- But separate and unseparate are functor-general. separate :: (Monad m, Functor f, Functor g) => Stream (Sum f g) m r -> Stream f (Stream g m) r unseparate :: (Monad m, Functor f, Functor g) => Stream f (Stream g m) r -> Stream (Sum f g) m r -- | Rearrange a succession of layers of the form Compose m (f x). -- -- we could as well define decompose by mapsM: -- --
-- decompose = mapped getCompose ---- -- but mapped is best understood as: -- --
-- mapped phi = decompose . maps (Compose . phi) ---- -- since maps and hoist are the really fundamental -- operations that preserve the shape of the stream: -- --
-- maps :: (Monad m, Functor f) => (forall x. f x -> g x) -> Stream f m r -> Stream g m r -- hoist :: (Monad m, Functor f) => (forall a. m a -> n a) -> Stream f m r -> Stream f n r --decompose :: (Monad m, Functor f) => Stream (Compose m f) m r -> Stream f m r -- | If Of had a Comonad instance, then we'd have -- --
-- copy = expand extend ---- -- See expandPost for a version that requires a Functor g -- instance instead. expand :: (Monad m, Functor f) => (forall a b. (g a -> b) -> f a -> h b) -> Stream f m r -> Stream g (Stream h m) r -- | If Of had a Comonad instance, then we'd have -- --
-- copy = expandPost extend ---- -- See expand for a version that requires a Functor f -- instance instead. expandPost :: (Monad m, Functor g) => (forall a b. (g a -> b) -> f a -> h b) -> Stream f m r -> Stream g (Stream h m) r -- | Map each layer to an effect, and run them all. mapsM_ :: (Functor f, Monad m) => (forall x. f x -> m x) -> Stream f m r -> m r -- | Run the effects in a stream that merely layers effects. run :: Monad m => Stream m m r -> m r -- | streamFold reorders the arguments of destroy to be more -- akin to foldr It is more convenient to query in ghci to -- figure out what kind of 'algebra' you need to write. -- --
-- >>> :t streamFold return join -- (Monad m, Functor f) => -- (f (m a) -> m a) -> Stream f m a -> m a -- iterT ---- --
-- >>> :t streamFold return (join . lift) -- (Monad m, Monad (t m), Functor f, MonadTrans t) => -- (f (t m a) -> t m a) -> Stream f m a -> t m a -- iterTM ---- --
-- >>> :t streamFold return effect -- (Monad m, Functor f, Functor g) => -- (f (Stream g m r) -> Stream g m r) -> Stream f m r -> Stream g m r ---- --
-- >>> :t \f -> streamFold return effect (wrap . f) -- (Monad m, Functor f, Functor g) => -- (f (Stream g m a) -> g (Stream g m a)) -- -> Stream f m a -> Stream g m a -- maps ---- --
-- >>> :t \f -> streamFold return effect (effect . fmap wrap . f) -- (Monad m, Functor f, Functor g) => -- (f (Stream g m a) -> m (g (Stream g m a))) -- -> Stream f m a -> Stream g m a -- mapped ---- --
-- streamFold done eff construct -- = eff . iterT (return . construct . fmap eff) . fmap done --streamFold :: (Functor f, Monad m) => (r -> b) -> (m b -> b) -> (f b -> b) -> Stream f m r -> b -- | Specialized fold following the usage of -- Control.Monad.Trans.Free -- --
-- iterTM alg = streamFold return (join . lift) -- iterTM alg = iterT alg . hoist lift --iterTM :: (Functor f, Monad m, MonadTrans t, Monad (t m)) => (f (t m a) -> t m a) -> Stream f m a -> t m a -- | Specialized fold following the usage of -- Control.Monad.Trans.Free -- --
-- iterT alg = streamFold return join alg -- iterT alg = runIdentityT . iterTM (IdentityT . alg . fmap runIdentityT) --iterT :: (Functor f, Monad m) => (f (m a) -> m a) -> Stream f m a -> m a -- | Map a stream to its church encoding; compare Data.List.foldr. -- destroyExposed may be more efficient in some cases when -- applicable, but it is less safe. -- --
-- destroy s construct eff done -- = eff . iterT (return . construct . fmap eff) . fmap done $ s -- --destroy :: (Functor f, Monad m) => Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b -- | A left-strict pair; the base functor for streams of individual -- elements. data Of a b (:>) :: !a -> b -> Of a b infixr 5 :> -- | 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 can restate some types as follows: -- --
-- mapOf :: (a -> b) -> Of a ~~> Of b -- Bifunctor first -- lazily :: Of a ~~> (,) a -- Identity . fst' :: Of a ~~> Identity a ---- -- Manipulation of a Stream f m r by mapping often turns on -- recognizing natural transformations of f. Thus maps -- is far more general the the map of the -- Streaming.Prelude, which can be defined thus: -- --
-- S.map :: (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r -- S.map f = maps (mapOf f) ---- -- i.e. -- --
-- S.map f = maps (\(a :> x) -> (f a :> x)) ---- -- 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 ---- -- Thus we can maps it in turn. lazily :: Of a b -> (a, b) -- | Convert a standard Haskell pair into a left-strict pair strictly :: (a, b) -> Of a b -- | A functor in the category of monads, using hoist as the analog -- of fmap: -- --
-- hoist (f . g) = hoist f . hoist g -- -- hoist id = id --class MFunctor (t :: Type -> Type -> k -> Type) -- | Lift a monad morphism from m to n into a monad -- morphism from (t m) to (t n) -- -- The first argument to hoist must be a monad morphism, even -- though the type system does not enforce this hoist :: forall m n (b :: k). (MFunctor t, Monad m) => (forall a. () => m a -> n a) -> t m b -> t n b -- | A monad in the category of monads, using lift from -- MonadTrans as the analog of return and embed as -- the analog of (=<<): -- --
-- embed lift = id -- -- embed f (lift m) = f m -- -- embed g (embed f t) = embed (\m -> embed g (f m)) t --class (MFunctor t, MonadTrans t) => MMonad (t :: Type -> Type -> Type -> Type) -- | Embed a newly created MMonad layer within an existing layer -- -- embed is analogous to (=<<) embed :: forall (n :: Type -> Type) m b. (MMonad t, Monad n) => (forall a. () => m a -> t n a) -> t m b -> t n b -- | The class of monad transformers. Instances should satisfy the -- following laws, which state that lift is a monad -- transformation: -- -- class MonadTrans (t :: Type -> Type -> Type -> Type) -- | Lift a computation from the argument monad to the constructed monad. lift :: (MonadTrans t, Monad m) => m a -> t m a -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | Right-to-left composition of functors. The composition of applicative -- functors is always applicative, but the composition of monads is not -- always a monad. newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) Compose :: f (g a) -> Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) [getCompose] :: Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) -> f (g a) infixr 9 `Compose` infixr 9 `Compose` -- | Lifted sum of functors. data Sum (f :: k -> Type) (g :: k -> Type) (a :: k) InL :: f a -> Sum (f :: k -> Type) (g :: k -> Type) (a :: k) InR :: g a -> Sum (f :: k -> Type) (g :: k -> Type) (a :: k) -- | Identity functor and monad. (a non-strict monad) newtype Identity a Identity :: a -> Identity a [runIdentity] :: Identity a -> a -- | A monoid on applicative functors. -- -- If defined, some and many should be the least solutions -- of the equations: -- -- class Applicative f => Alternative (f :: Type -> Type) -- | An associative binary operation (<|>) :: Alternative f => f a -> f a -> f a infixl 3 <|> -- | A bifunctor is a type constructor that takes two type arguments and is -- a functor in both arguments. That is, unlike with -- Functor, a type constructor such as Either does not need -- to be partially applied for a Bifunctor instance, and the -- methods in this class permit mapping functions over the Left -- value or the Right value, or both at the same time. -- -- Formally, the class Bifunctor represents a bifunctor from -- Hask -> Hask. -- -- Intuitively it is a bifunctor where both the first and second -- arguments are covariant. -- -- You can define a Bifunctor by either defining bimap or -- by defining both first and second. -- -- If you supply bimap, you should ensure that: -- --
-- bimap id id ≡ id ---- -- If you supply first and second, ensure: -- --
-- first id ≡ id -- second id ≡ id ---- -- If you supply both, you should also ensure: -- --
-- bimap f g ≡ first f . second g ---- -- These ensure by parametricity: -- --
-- bimap (f . g) (h . i) ≡ bimap f h . bimap g i -- first (f . g) ≡ first f . first g -- second (f . g) ≡ second f . second g --class Bifunctor (p :: Type -> Type -> Type) -- | Map over both arguments at the same time. -- --
-- bimap f g ≡ first f . second g ---- --
-- >>> bimap toUpper (+1) ('j', 3)
-- ('J',4)
--
--
-- -- >>> bimap toUpper (+1) (Left 'j') -- Left 'J' ---- --
-- >>> bimap toUpper (+1) (Right 3) -- Right 4 --bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d -- | Map covariantly over the first argument. -- --
-- first f ≡ bimap f id ---- --
-- >>> first toUpper ('j', 3)
-- ('J',3)
--
--
-- -- >>> first toUpper (Left 'j') -- Left 'J' --first :: Bifunctor p => (a -> b) -> p a c -> p b c -- | Map covariantly over the second argument. -- --
-- second ≡ bimap id ---- --
-- >>> second (+1) ('j', 3)
-- ('j',4)
--
--
-- -- >>> second (+1) (Right 3) -- Right 4 --second :: Bifunctor p => (b -> c) -> p a b -> p a c -- | The join function is the conventional monad join operator. It -- is used to remove one level of monadic structure, projecting its bound -- argument into the outer level. -- -- 'join bss' can be understood as the do -- expression -- --
-- do bs <- bss -- bs ---- --
-- atomically :: STM a -> IO a ---- -- is used to run STM transactions atomically. So, by specializing -- the types of atomically and join to -- --
-- atomically :: STM (IO b) -> IO (IO b) -- join :: IO (IO b) -> IO b ---- -- we can compose them as -- --
-- join . atomically :: STM (IO b) -> IO b ---- -- to run an STM transaction and the IO action it returns. join :: Monad m => m (m a) -> m a -- | Promote a function to a monad. liftM :: Monad m => (a1 -> r) -> m a1 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right. For example, -- --
-- liftM2 (+) [0,1] [0,2] = [0,2,1,3] -- liftM2 (+) (Just 1) Nothing = Nothing --liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r -- | Lift a binary function to actions. -- -- Some functors support an implementation of liftA2 that is more -- efficient than the default one. In particular, if fmap is an -- expensive operation, it is likely better to use liftA2 than to -- fmap over the structure and then use <*>. -- -- This became a typeclass method in 4.10.0.0. Prior to that, it was a -- function defined in terms of <*> and fmap. -- -- Using ApplicativeDo: 'liftA2 f as bs' can be -- understood as the do expression -- --
-- do a <- as -- b <- bs -- pure (f a b) --liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c -- | Lift a ternary function to actions. -- -- Using ApplicativeDo: 'liftA3 f as bs cs' can -- be understood as the do expression -- --
-- do a <- as -- b <- bs -- c <- cs -- pure (f a b c) --liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d -- | void value discards or ignores the result of -- evaluation, such as the return value of an IO action. -- -- Using ApplicativeDo: 'void as' can be -- understood as the do expression -- --
-- do as -- pure () ---- -- with an inferred Functor constraint. -- --
-- >>> void Nothing -- Nothing -- -- >>> void (Just 3) -- Just () ---- -- Replace the contents of an Either Int -- Int with unit, resulting in an Either -- Int (): -- --
-- >>> void (Left 8675309) -- Left 8675309 -- -- >>> void (Right 8675309) -- Right () ---- -- Replace every element of a list with unit: -- --
-- >>> void [1,2,3] -- [(),(),()] ---- -- Replace the second element of a pair with unit: -- --
-- >>> void (1,2) -- (1,()) ---- -- Discard the result of an IO action: -- --
-- >>> mapM print [1,2] -- 1 -- 2 -- [(),()] -- -- >>> void $ mapM print [1,2] -- 1 -- 2 --void :: Functor f => f a -> f () -- | An associative operation. -- --
-- >>> [1,2,3] <> [4,5,6] -- [1,2,3,4,5,6] --(<>) :: Semigroup a => a -> a -> a infixr 6 <>