HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Modulestreaming-0.2.4.0Haskell2010

Streaming.Prelude

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
--------------------------------------------------------------------------------------------------------------------
  • 2 types
  • 142 values
  • Packagestreaming-0.2.4.0
  • Exports144
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourcePrelude.hs

Types

1 declaration
datadata Of a b
#

A left-strict pair; the base functor for streams of individual elements.

Constructors

  • a :> binfixr 5
Instances25Bifoldable, Bifunctor, Bitraversable, Eq2, Ord2, Show2, …

Introducing streams of elements

18 declarations
valueyield :: Monad m => a -> Stream (Of a) m ()
#

A singleton stream

Example1 expression
stdoutLn $ yield "hello"hello
Example1 expression
S.sum $ do {yield 1; yield 2; yield 3}6 :> ()
Example2 expressions
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] :> ()
valueeach :: (Monad m, Foldable f) => f a -> Stream (Of a) m ()
#

Stream the elements of a pure, foldable container.

Example1 expression
S.print $ each [1..3]123
valuestdinLn :: MonadIO m => Stream (Of String) 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

Example1 expression
stdoutLn stdinLnhello<Enter>helloworld<Enter>world^CInterrupted.
Example1 expression
stdoutLn $ S.map reverse stdinLnhello<Enter>ollehworld<Enter>dlrow^CInterrupted.
valuereadLn :: (MonadIO m, Read a) => Stream (Of a) m ()
#

Read values from stdin, ignoring failed parses.

Example2 expressions
:set -XTypeApplicationsS.sum $ S.take 2 (S.readLn @IO @Int)10<Enter>12<Enter>22 :> ()
Example1 expression
S.toList $ S.take 2 (S.readLn @IO @Int)10<Enter>1@#$%^&*\<Enter>12<Enter>[10,12] :> ()
valuereadFile :: FilePath -> (Stream (Of String) IO () -> IO a) -> IO a
#

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'.

Example2 expressions
S.writeFile "lines.txt" $ S.take 2 S.stdinLnhello<Enter>world<Enter>S.readFile "lines.txt" S.print"hello""world"
valueiterate :: Monad m => (a -> a) -> a -> Stream (Of a) m r
#

Iterate a pure function from a seed value, streaming the results forever

valueiterateM :: Monad m => (a -> m a) -> m a -> Stream (Of a) m r
#

Iterate a monadic function from a seed value, streaming the results forever

valuerepeat :: Monad m => a -> Stream (Of a) m r
#

Repeat an element ad inf. .

Example1 expression
S.print $ S.take 3 $ S.repeat 1111
valuerepeatM :: Monad m => m a -> Stream (Of a) m r
#

Repeat a monadic action ad inf., streaming its results.

Example1 expression
S.toList $ S.take 2 $ repeatM getLineone<Enter>two<Enter>["one","two"]
valuecycle :: (Monad m, Functor f) => Stream f m r -> Stream f m s
#

Cycle repeatedly through the layers of a stream, ad inf. This function is functor-general

cycle = forever
Example2 expressions
rest <- S.print $ S.splitAt 3 $ S.cycle (yield True >> yield False)TrueFalseTrueS.print $ S.take 3 restFalseTrueFalse
valuereplicateM :: Monad m => Int -> m a -> Stream (Of a) m ()
#

Repeat an action several times, streaming its results.

Example1 expression
S.print $ S.replicateM 2 getCurrentTime2015-08-18 00:57:36.124508 UTC2015-08-18 00:57:36.124785 UTC
valueenumFrom :: (Monad m, Enum n) => n -> Stream (Of n) m r
#

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:

Example2 expressions
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'
valueenumFromThen :: (Monad m, Enum a) => a -> a -> Stream (Of a) m r
#

An infinite sequence of enumerable values at a fixed distance, determined by the first and second values. See the discussion of Streaming.enumFrom

Example1 expression
S.print $ S.take 3 $ S.enumFromThen 100 200100200300
valueunfoldr :: Monad m => (s -> m (Either r (a, s))) -> s -> 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 Pipes.Producer. Consider:

Example1 expression
S.stdoutLn $ S.take 2 $ S.unfoldr Pipes.next Pipes.stdinLnhello<Enter>hellogoodbye<Enter>goodbye
Example1 expression
S.stdoutLn $ S.unfoldr Pipes.next (Pipes.stdinLn >-> Pipes.take 2)hello<Enter>hellogoodbye<Enter>goodbye
Example1 expression
S.effects $ S.unfoldr Pipes.next (Pipes.stdinLn >-> Pipes.take 2 >-> Pipes.stdoutLn)hello<Enter>hellogoodbye<Enter>goodbye

Pipes.unfoldr S.next similarly unfolds a Pipes.Producer from a stream.

Consuming streams of elements

9 declarations
valuestdoutLn :: MonadIO m => Stream (Of String) m () -> m ()
#

Write Strings to stdout using putStrLn; terminates on a broken output pipe (The name and implementation are modelled on the Pipes.Prelude stdoutLn).

Example1 expression
S.stdoutLn $ S.take 3 $ S.each $ words "one two three four five"onetwothree
valuestdoutLn' :: MonadIO m => Stream (Of String) m r -> m r
#

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:

Example2 expressions
rest <- S.stdoutLn' $ S.show $ S.splitAt 3 (each [1..5])123S.toList rest[4,5] :> ()
valuemapM_ :: Monad m => (a -> m x) -> Stream (Of a) m r -> m r
#

Reduce a stream to its return value with a monadic action.

Example1 expression
S.mapM_ Prelude.print $ each [1..3]123
Example2 expressions
rest <- S.mapM_ Prelude.print $ S.splitAt 3 $ each [1..10]123S.sum rest49 :> ()
valueprint :: (MonadIO m, Show a) => Stream (Of a) m r -> m r
#

Print the elements of a stream as they arise.

Example1 expression
S.print $ S.take 2 S.stdinLnhello<Enter>"hello"world<Enter>"world"
valuetoHandle :: MonadIO m => Handle -> Stream (Of String) m r -> m r
#

Write a succession of strings to a handle as separate lines.

Example1 expression
S.toHandle IO.stdout $ each (words "one two three")onetwothree
valuewriteFile :: FilePath -> Stream (Of String) IO r -> IO r
#

Write a series of Strings as lines to a file.

Example1 expression
S.writeFile "lines.txt" $ S.take 2 S.stdinLnhello<Enter>world<Enter>
Example1 expression
S.readFile "lines.txt" S.stdoutLnhelloworld
valueeffects :: Monad m => Stream (Of a) m r -> m r
#

Reduce a stream, performing its actions but ignoring its elements.

Example2 expressions
rest <- S.effects $ S.splitAt 2 $ each [1..5]S.print rest345

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.

valuedrained
  1. :: (Monad m, Monad (t m), MonadTrans t)
  2. => t m (Stream (Of a) m r)
  3. -> t 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:

Example2 expressions
rest <- S.print $ S.drained $ S.splitAt 2 $ S.splitAt 5 $ each [1..7]12S.print rest67

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

Stream transformers

43 declarations
valuemap :: Monad m => (a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
#

Standard map on the elements of a stream.

Example1 expression
S.stdoutLn $ S.map reverse $ each (words "alpha beta")ahplaateb
valuemapM :: Monad m => (a -> m b) -> Stream (Of a) m r -> Stream (Of b) m r
#

Replace each element of a stream with the result of a monadic action

Example1 expression
S.print $ S.mapM readIORef $ S.chain (\ior -> modifyIORef ior (*100)) $ S.mapM newIORef $ each [1..6]100200300400500600

See also chain for a variant of this which ignores the return value of the function and just uses the side effects.

valuemaps
  1. :: (Monad m, Functor f)
  2. => forall x. f x -> g x
  3. -> Stream f m r
  4. -> 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.

maps id = id
maps f . maps g = maps (f . g)
valuemapsPost
  1. :: (Monad m, Functor g)
  2. => forall x. f x -> g x
  3. -> Stream f m r
  4. -> 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.

valuemapped
  1. :: (Monad m, Functor f)
  2. => forall x. f x -> m (g x)
  3. -> Stream f m r
  4. -> 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:

Example1 expression
S.toList_ $ S.mapped S.toList $ S.split 'c' (S.each "abcde")["ab","de"]

Streaming.Prelude.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)

Streaming.Prelude.maps is more fundamental than mapped, which is best understood as a convenience for effecting this frequent composition:

mapped phi = decompose . maps (Compose . phi)
valuemappedPost
  1. :: (Monad m, Functor g)
  2. => forall x. f x -> m (g x)
  3. -> Stream f m r
  4. -> 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.

valuefor
  1. :: (Monad m, Functor f)
  2. => Stream (Of a) m r
  3. -> a -> Stream f m x
  4. -> Stream f m r
#

for replaces each element of a stream with an associated stream. Note that the associated stream may layer any functor.

valuewith
  1. :: (Monad m, Functor f)
  2. => Stream (Of a) m r
  3. -> a -> f x
  4. -> 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
Example1 expression
with (each [1..3]) (yield . Prelude.show) & intercalates (yield "--") & S.stdoutLn1--2--3
valuesubst
  1. :: (Monad m, Functor f)
  2. => a -> f x
  3. -> Stream (Of a) m r
  4. -> 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
valuecopy :: Monad m => Stream (Of a) m r -> Stream (Of a) (Stream (Of a) 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:

Example2 expressions
S.print $ each ["one","two"]"one""two"S.stdoutLn $ each ["one","two"]onetwo

With copy, I can do these simultaneously:

Example1 expression
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 Data.ByteString.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 Control.Foldl, e.g.

Example1 expression
L.purely S.fold (liftA2 (,) L.sum L.product) $ each [1..10](55,3628800) :> ()

rather than

Example1 expression
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 Data.List-like, using copy:

Example1 expression
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

Example1 expression
S.sum $ S.filter odd $ S.product $ S.filter even $ S.copy $ each [1..10]25 :> (3840 :> ())

or using store

Example1 expression
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:

Example1 expression
(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:

Example1 expression
(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
valuestore
  1. :: Monad m
  2. => Stream (Of a) (Stream (Of a) m) r -> t
  3. -> Stream (Of a) m r
  4. -> t
#

Store the result of any suitable fold over a stream, keeping the stream for further manipulation. store f = f . copy :

Example1 expression
S.print $ S.store S.product $ each [1..4]123424 :> ()
Example1 expression
S.print $ S.store S.sum $ S.store S.product $ each [1..4]123410 :> (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:

Example1 expression
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]1234(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:

Example1 expression
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:

Example3 expressions
(S.writeFile "hello2.txt" . S.nubOrd) $ store (S.writeFile "hello.txt" . S.filter (/= "world")) $ each ["hello", "world", "goodbye", "world"]:! cat hello.txthellogoodbye:! cat hello2.txthelloworldgoodbye
valuechain :: Monad m => (a -> m y) -> Stream (Of a) m r -> Stream (Of a) m r
#

Apply an action to all values, re-yielding each. The return value (y) of the function is ignored.

Example1 expression
S.product $ S.chain Prelude.print $ S.each [1..5]12345120 :> ()

See also mapM for a variant of this which uses the return value of the function to transorm the values in the stream.

valuesequence :: Monad m => Stream (Of (m a)) m r -> Stream (Of a) m r
#

Like the Data.List.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

valuenubOrd :: (Monad m, Ord a) => Stream (Of 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.

Example1 expression
S.toList_ $ S.nubOrd $ S.take 5 S.readLn :: IO [Int]1<Enter>2<Enter>3<Enter>1<Enter>2<Enter>[1,2,3]
valueintersperse :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) m r
#

Intersperse given value between each element of the stream.

Example1 expression
S.print $ S.intersperse 0 $ each [1,2,3]10203
valuetake :: (Monad m, Functor f) => Int -> Stream f m r -> Stream f m ()
#

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.

Example1 expression
S.toList $ S.take 3 $ each "with""wit" :> ()
Example1 expression
S.readFile "stream.hs" (S.stdoutLn . S.take 3)import Streamingimport qualified Streaming.Prelude as Simport Streaming.Prelude (each, next, yield)
valuetakeWhile
  1. :: Monad m
  2. => a -> Bool
  3. -> Stream (Of a) m r
  4. -> Stream (Of a) 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
valuedrop :: Monad m => Int -> Stream (Of a) m r -> Stream (Of a) m r
#

Ignore the first n elements of a stream, but carry out the actions

Example1 expression
S.toList $ S.drop 2 $ S.replicateM 5 getLinea<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:

Example1 expression
S.toList $ concats $ maps (S.drop 4) $ chunksOf 5 $ each [1..20][5,10,15,20] :> ()
valuedropWhile
  1. :: Monad m
  2. => a -> Bool
  3. -> Stream (Of a) m r
  4. -> Stream (Of a) m r
#

Ignore elements of a stream until a test succeeds, retaining the rest.

Example1 expression
S.print $ S.dropWhile ((< 5) . length) S.stdinLnone<Enter>two<Enter>three<Enter>"three"four<Enter>"four"^CInterrupted.
valueconcat
  1. :: (Monad m, Foldable f)
  2. => Stream (Of (f a)) m r
  3. -> 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
Example1 expression
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.

Example3 expressions
S.print $ S.concat $ S.each [Just 1, Nothing, Just 2]12S.print $  S.concat $ S.each [Right 1, Left "Error!", Right 2]12S.print $ S.concat $ S.each [('A',1), ('B',2)]12
valuescan
  1. :: Monad m
  2. => x -> a -> x
  3. -> x
  4. -> x -> b
  5. -> Stream (Of a) m r
  6. -> Stream (Of b) 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.

Example1 expression
S.print $ S.scan (++) "" id $ each (words "a b c d")"""a""ab""abc""abcd"

scan is fitted for use with Control.Foldl, thus:

Example1 expression
S.print $ L.purely S.scan L.list $ each [3..5][][3][3,4][3,4,5]
valuescanM
  1. :: Monad m
  2. => x -> a -> m x
  3. -> m x
  4. -> x -> m b
  5. -> Stream (Of a) m r
  6. -> 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

Example2 expressions
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]
valuescanned
  1. :: Monad m
  2. => x -> a -> x
  3. -> x
  4. -> x -> b
  5. -> Stream (Of a) m r
  6. -> Stream (Of (a, b)) m r
#

Label each element in a stream with a value accumulated according to a fold.

Example1 expression
S.print $ S.scanned (*) 1 id $ S.each [100,200,300](100,100)(200,20000)(300,6000000)
Example1 expression
S.print $ L.purely S.scanned L.product $ S.each [100,200,300](100,100)(200,20000)(300,6000000)
valueread :: (Monad m, Read a) => Stream (Of String) m r -> Stream (Of a) m r
#

Make a stream of strings into a stream of parsed values, skipping bad cases

Example1 expression
S.sum_ $ S.read $ S.takeWhile (/= "total") S.stdinLn :: IO Int1000<Enter>2000<Enter>total<Enter>3000
valuecons :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) 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.

valueslidingWindow
  1. :: Monad m
  2. => Int
  3. -> Stream (Of a) m b
  4. -> Stream (Of (Seq a)) m b
#

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.

Example1 expression
S.print $ S.slidingWindow 4 $ S.each "123456"fromList "1234"fromList "2345"fromList "3456"
valueslidingWindowMin
  1. :: (Monad m, Ord a)
  2. => Int
  3. -> Stream (Of a) m b
  4. -> Stream (Of 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.

valueslidingWindowMinBy
  1. :: Monad m
  2. => a -> a -> Ordering
  3. -> Int
  4. -> Stream (Of a) m b
  5. -> 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.

valueslidingWindowMinOn
  1. :: (Monad m, Ord p)
  2. => a -> p
  3. -> Int
  4. -> Stream (Of a) m b
  5. -> 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 (Foldable.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.

valueslidingWindowMax
  1. :: (Monad m, Ord a)
  2. => Int
  3. -> Stream (Of a) m b
  4. -> 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.

valueslidingWindowMaxBy
  1. :: Monad m
  2. => a -> a -> Ordering
  3. -> Int
  4. -> Stream (Of a) m b
  5. -> 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.

valueslidingWindowMaxOn
  1. :: (Monad m, Ord p)
  2. => a -> p
  3. -> Int
  4. -> Stream (Of a) m b
  5. -> 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 (Foldable.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.

valuewrapEffect
  1. :: (Monad m, Functor f)
  2. => m a
  3. -> a -> m y
  4. -> Stream f m r
  5. -> Stream f m r
#

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.

Splitting and inspecting streams of elements

10 declarations
valuenext :: Monad m => Stream (Of a) m r -> m (Either r (a, Stream (Of a) 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

valueuncons :: Monad m => Stream (Of a) m r -> m (Maybe (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
valuesplitAt
  1. :: (Monad m, Functor f)
  2. => Int
  3. -> Stream f m r
  4. -> Stream f m (Stream f 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)
valuesplit
  1. :: (Eq a, Monad m)
  2. => a
  3. -> Stream (Of a) m r
  4. -> Stream (Stream (Of a) m) m r
#

Split a stream of elements wherever a given element arises. The action is like that of words.

Example1 expression
S.stdoutLn $ mapped S.toList $ S.split ' ' $ each "hello world  "helloworld
valuebreaks
  1. :: Monad m
  2. => a -> Bool
  3. -> Stream (Of a) m r
  4. -> Stream (Stream (Of a) m) m r
#

Break during periods where the predicate is not satisfied, grouping the periods when it is.

Example2 expressions
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]
valuebreak
  1. :: Monad m
  2. => a -> Bool
  3. -> Stream (Of a) m r
  4. -> Stream (Of a) m (Stream (Of a) m r)
#

Break a sequence upon meeting element falls under a predicate, keeping it and the rest of the stream as the return value.

Example2 expressions
rest <- S.print $ S.break even $ each [1,1,2,3]11S.print rest23
valuebreakWhen
  1. :: Monad m
  2. => x -> a -> x
  3. -> x
  4. -> x -> b
  5. -> b -> Bool
  6. -> Stream (Of a) m r
  7. -> 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

Example2 expressions
rest <- each [1..10] & L.purely S.breakWhen L.sum (>10) & S.print1234S.print rest5678910
valuegroup
  1. :: (Monad m, Eq a)
  2. => Stream (Of a) m r
  3. -> Stream (Stream (Of a) m) m r
#

Group successive equal items together

Example1 expression
S.toList $ mapped S.toList $ S.group $ each "baaaaad"["b","aaaaa","d"] :> ()
Example1 expression
S.toList $ concats $ maps (S.drained . S.splitAt 1) $ S.group $ each "baaaaaaad""bad" :> ()
valuegroupBy
  1. :: Monad m
  2. => a -> a -> Bool
  3. -> Stream (Of a) m r
  4. -> Stream (Stream (Of a) m) m r
#

Group elements of a stream in accordance with the supplied comparison.

Example1 expression
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]

Sum and Compose manipulation

8 declarations
valueswitch :: Sum f g r -> Sum g f r
#

Swap the order of functors in a sum of functors.

Example2 expressions
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" :> ()
valueseparate
  1. :: (Monad m, Functor f, Functor g)
  2. => Stream (Sum f g) m r
  3. -> Stream f (Stream g 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.

Example2 expressions
let odd_even = S.maps (S.distinguish even) $ S.each [1..10::Int]:t separate odd_evenseparate 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:

Example1 expression
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:

Example3 expressions
S.writeFile "even.txt" . S.show $ S.writeFile "odd.txt" . S.show $ S.separate odd_even:! cat even.txt246810:! cat odd.txt13579

Of course, in the special case of Stream (Of a) m r, we can achieve the above effects more simply by using copy

Example1 expression
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.

Folds

34 declarations

Use these to fold the elements of a Stream.

Example1 expression
S.fold_ (+) 0 id $ S.each [1..10]55

The general folds fold, fold_, foldM and foldM_ are arranged for use with Control.Foldl purely and impurely

Example2 expressions
L.purely fold_ L.sum $ each [1..10]55L.purely fold_ (liftA3 (,,) L.sum L.product L.list) $ each [1..10](55,3628800,[1,2,3,4,5,6,7,8,9,10])

All functions marked with an underscore (e.g. fold_, sum_) omit the stream's return value in a left-strict pair. They are good for exiting streaming completely, but when you are, e.g. mapped-ing over a Stream (Stream (Of a) m) m r, which is to be compared with [[a]]. Specializing, we have e.g.

 mapped sum :: (Monad m, Num n) => Stream (Stream (Of Int)) IO () -> Stream (Of n) IO ()
 mapped (fold mappend mempty id) :: Stream (Stream (Of Int)) IO () -> Stream (Of Int) IO ()
Example1 expression
S.print $ mapped S.sum $ chunksOf 3 $ S.each [1..10]6152410
Example2 expressions
let three_folds = L.purely S.fold (liftA3 (,,) L.sum L.product L.list)S.print $ mapped three_folds $ chunksOf 3 (each [1..10])(6,6,[1,2,3])(15,120,[4,5,6])(24,504,[7,8,9])(10,10,[10])
valuefold
  1. :: Monad m
  2. => x -> a -> x
  3. -> x
  4. -> x -> b
  5. -> Stream (Of a) m r
  6. -> m (Of b 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:

Example1 expression
S.fold (+) 0 id $ each [1..10]55 :> ()
Example1 expression
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.

Example1 expression
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)
valuefold_
  1. :: Monad m
  2. => x -> a -> x
  3. -> x
  4. -> x -> b
  5. -> Stream (Of a) m r
  6. -> m b
#

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:

Example1 expression
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
valuefoldM
  1. :: Monad m
  2. => x -> a -> m x
  3. -> m x
  4. -> x -> m b
  5. -> Stream (Of a) m r
  6. -> 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 r -> m (b, r)

Thus to accumulate the elements of a stream as a vector, together with a random element we might write:

Example1 expression
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) :> ()
valuefoldM_
  1. :: Monad m
  2. => x -> a -> m x
  3. -> m x
  4. -> x -> m b
  5. -> Stream (Of a) m r
  6. -> 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 () -> m b
valuefoldMap
  1. :: (Monad m, Monoid w)
  2. => a -> w
  3. -> Stream (Of a) m r
  4. -> m (Of w r)
#

Map each element of the stream to a monoid, and take the monoidal sum of the results.

Example1 expression
S.foldMap Sum $ S.take 2 (S.stdinLn)1<Enter>2<Enter>3<Enter>Sum {getSum = 6} :> ()
valuesum :: (Monad m, Num a) => Stream (Of a) m r -> m (Of a r)
#

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
Example1 expression
S.sum $ each [1..10]55 :> ()
Example5 expressions
(n :> rest)  <- S.sum $ S.splitAt 3 $ each [1..10]System.IO.print n6(m :> rest') <- S.sum $ S.splitAt 3 restSystem.IO.print m15S.print rest'78910
valueproduct :: (Monad m, Num a) => Stream (Of a) m r -> m (Of a r)
#

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
valueelem :: (Monad m, Eq a) => a -> Stream (Of a) m r -> m (Of Bool r)
#

Exhaust a stream remembering only whether a was an element.

valuelength :: Monad m => Stream (Of a) m r -> m (Of Int r)
#

Run a stream, keeping its length and its return value.

Example1 expression
S.print $ mapped S.length $ chunksOf 3 $ S.each [1..10]3331
valuelength_ :: Monad m => Stream (Of a) m r -> m Int
#

Run a stream, remembering only its length:

Example1 expression
runIdentity $ S.length_ (S.each [1..10] :: Stream (Of Int) Identity ())10
valuetoList :: Monad m => Stream (Of a) m r -> m (Of [a] r)
#

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

Example1 expression
S.print $ mapped S.toList $ chunksOf 3 $ each [1..9][1,2,3][4,5,6][7,8,9]
Example1 expression
S.print $ mapped S.toList $ chunksOf 2 $ S.replicateM 4 getLines<Enter>t<Enter>["s","t"]u<Enter>v<Enter>["u","v"]
valuetoList_ :: Monad m => Stream (Of a) m r -> m [a]
#

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.

valuemconcat :: (Monad m, Monoid w) => Stream (Of w) m r -> m (Of w r)
#

Fold streamed items into their monoidal sum

Example1 expression
S.mconcat $ S.take 2 $ S.map (Data.Monoid.Last . Just) S.stdinLnfirst<Enter>last<Enter>Last {getLast = Just "last"} :> ()
valuefoldrM :: 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 iterT in the Streaming module and the still more general destroy

valuefoldrT
  1. :: (Monad m, MonadTrans t, Monad (t m))
  2. => a -> t m r -> t m r
  3. -> Stream (Of a) m r
  4. -> t 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

Zips and unzips

7 declarations
valueunzip
  1. :: Monad m
  2. => Stream (Of (a, b)) m r
  3. -> Stream (Of a) (Stream (Of b) 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:

Example1 expression
let xs = Prelude.map (\x -> (x, Prelude.show x)) [1..5 :: Int]
Example1 expression
S.toList $ S.toList $ S.unzip (S.each xs)["1","2","3","4","5"] :> ([1,2,3,4,5] :> ())
Example1 expression
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:

Example1 expression
:t S.unzip $ S.each xsS.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:

Example1 expression
:t S.toList $ S.unzip $ S.each xsS.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:

Example1 expression
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)
valuepartitionEithers
  1. :: Monad m
  2. => Stream (Of (Either a b)) m r
  3. -> 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:

Example1 expression
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

Merging streams

3 declarations

These functions combine two sorted streams of orderable elements into one sorted stream. The elements of the merged stream are guaranteed to be in a sorted order if the two input streams are also sorted.

The merge operation is left-biased: when merging two elements that compare as equal, the left element is chosen first.

valuemerge
  1. :: (Monad m, Ord a)
  2. => Stream (Of a) m r
  3. -> Stream (Of a) m s
  4. -> Stream (Of a) m (r, s)
#

Merge two streams of elements ordered with their Ord instance.

The return values of both streams are returned.

Example1 expression
S.print $ merge (each [1,3,5]) (each [2,4])12345((), ())
valuemergeOn
  1. :: (Monad m, Ord b)
  2. => a -> b
  3. -> Stream (Of a) m r
  4. -> Stream (Of a) m s
  5. -> 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.

valuemergeBy
  1. :: Monad m
  2. => a -> a -> Ordering
  3. -> Stream (Of a) m r
  4. -> Stream (Of a) m s
  5. -> 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.

Maybes

2 declarations

These functions discard the Nothings that they encounter. They are analogous to the functions from Data.Maybe that share their names.

Pair manipulation

7 declarations
valuelazily :: Of a b -> (a, b)
#

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.

valuestrictly :: (a, b) -> Of a b
#

Convert a standard Haskell pair into a left-strict pair

valuefst' :: Of a b -> a
#

fst' and snd' extract the first and second element of a pair

Example2 expressions
S.fst' (1:>"hi")1S.snd' (1:>"hi")"hi"

They are contained in the _first and _second lenses, if any lens library is in scope

Example3 expressions
import Lens.Micro(1:>"hi") ^. S._first1(1:>"hi") ^. S._second"hi"
valuemapOf :: (a -> b) -> Of a r -> Of b r
#

Map a function over the first element of an Of pair

Example1 expression
S.mapOf even (1:>"hi")False :> "hi"

mapOf is just first from the Bifunctor instance

Example1 expression
first even (1:>"hi")False :> "hi"

and is contained in the _first lens

Example2 expressions
import Lens.Microover S._first even (1:>"hi")False :> "hi"
value_first :: Functor f => (a -> f a') -> Of a b -> f (Of a' b)
#

A lens into the first element of a left-strict pair

value_second :: Functor f => (b -> f b') -> Of a b -> f (Of a b')
#

A lens into the second element of a left-strict pair

Interoperation

1 declaration
valuereread :: Monad m => (s -> m (Maybe a)) -> s -> Stream (Of a) m ()
#

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 ()

Basic Type

1 declaration
datadata Stream (f :: Type -> Type) (m :: Type -> Type) r
#
Instances21MFunctor, MonadError, MonadReader, MonadState, MonadTrans, MMonad, …