'k      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij (c) 2017 Harendra KumarBSD3harendra.kumar@gmail.com experimentalGHCSafeXRun an action forever periodically at the given frequency specified in per second (Hz).Run a computation on every clock tick, the clock runs at the specified frequency. It allows running a computation at high frequency efficiently by maintaining a local clock and adjusting it with the provided base clock at longer intervals. The first argument is a base clock returning some notion of time in microseconds. The second argument is the frequency in per second (Hz). The third argument is the action to run, the action is provided the local time as an argument. (c) 2017 Harendra KumarBSD3harendra.kumar@gmail.com experimentalGHCNone *9:;<=OTA monad that can perform asynchronous/concurrent IO operations. Streams that can be composed concurrently require the underlying monad to be .k.Represents a monadic stream of values of type a% constructed using actions in monad m. Streams can be composed sequentially or in parallel; in product style compositions (monadic bind multiplies streams in a ListT fashion) or in sum style compositions like , ,  or variants of these.lVAn SVar or a Stream Var is a conduit to the output from multiple streams running concurrently and asynchronously. An SVar can be thought of as an asynchronous IO handle. We can write any number of streams to an SVar in a non-blocking manner and then read them back at any time at any pace. The SVar would run the streams asynchronously and accumulate results. An SVar may not really execute the stream completely and accumulate all the results. However, it ensures that the reader can read the results at whatever paces it wants to read. The SVar monitors and adapts to the consumer's pace.An SVar is a mini scheduler, it has an associated runqueue that holds the stream tasks to be picked and run by a pool of worker threads. It has an associated output queue where the output stream elements are placed by the worker threads. A doorBell is used by the worker threads to intimate the consumer thread about availability of new results in the output queue. More workers are added to the SVar by m" on demand if the output produced is not keeping pace with the consumer. On bounded SVars, workers block on the output queue to provide throttling of the producer when the consumer is not pulling fast enough. The number of workers may even get reduced depending on the consuming pace.{New work is enqueued either at the time of creation of the SVar or as a result of executing the parallel combinators i.e. <| and  < when the already enqueued computations get evaluated. See n.ohIdentify the type of the SVar. Two computations using the same style can be scheduled on the same SVar.p~For fairly interleaved parallel composition the sched policy is FIFO whereas for left biased parallel composition it is LIFO.qConjunction is used for monadic/product style composition. Disjunction is used for fold/sum style composition. We need to distiguish the two types of SVars so that the scheduling of the two is independent.r7Events that a child thread may send to a parent thread.sSame as <=>.mPull a stream from an SVar.tCreate a new empty SVar.u;Create a new SVar and enqueue one stream computation on it.v<Create a new SVar and enqueue two stream computations on it.wWrite a stream to an lQ in a non-blocking manner. The stream can then be read back from the SVar using fromSVar.n/Join two computations on the currently running l& queue for concurrent execution. The o required by the current composition context is passed as one of the parameters. If the style does not match with the style of the current l we create a new l| and schedule the computations on that. The newly created SVar joins as one of the computations on the current SVar queue.When we are using parallel composition, an SVar is passed around as a state variable. We try to schedule a new parallel computation on the SVar passed to us. The first time, when no SVar exists, a new SVar is created. Subsequently, n may get called when a computation already scheduled on the SVar is further evaluated. For example, when (a <|> b) is evaluated it calls a n to put a and b on the current scheduler queue. However, if the scheduling and composition style of the new computation being scheduled is different than the style of the current SVar, then we create a new SVar and schedule it on that. For example:E(x <|> y) <|> (t <|> u) -- all of them get scheduled on the same SVar(x <|> y) <|> (t <| u) -- t and uN get scheduled on a new child SVar because of the scheduling policy change.if we adapt a stream of type AsyncT to a stream of type  ParallelT1, we create a new SVar at the transitioning bind.When the stream is switching from disjunctive composition to conjunctive composition and vice-versa we create a new SVar to isolate the scheduling of the two.xSame as  x. Since this schedules all the composed streams fairly you cannot fold infinite number of streams using this operation.ySame as <|0. Since this schedules the left side computation first you can right fold an infinite container using this operator. However a left fold will not work well as it first unpeels the whole structure before scheduling a computation requiring an amount of memory proportional to the size of the structure.z g represents an action that takes non-zero time to complete. Since all actions take non-zero time, an  composition ( R) is a monoidal composition executing all actions in parallel, it is similar to W except that it runs all the actions in parallel and interleaves their results fairly.{ concatenates two streams sequentially i.e. the first stream is exhausted completely before yielding any element from the second stream.Ak|}l~opqrsmtuvwnxyz{k|}lopqsmtuvwnxy0k|}l~opqrsmtuvwnxyz{ (c) 2017 Harendra KumarBSD3harendra.kumar@gmail.com experimentalGHCNone /9:;<=IOT$Like Q but zips in parallel, it generates both the elements to be zipped concurrently. main = (toList . *` $ (,) <$> s1 <*> s2) >>= print where s1 = pure 1 <> pure 2 s2 = pure 3 <> pure 4  [(1,3),(2,4)] _This applicative operation can be seen as the zipping equivalent of parallel composition with  . zips serially i.e. it produces one element from each stream serially and then zips the two elements. Note, for convenience we have used the )I combinator in the following example instead of using a type annotation. main = (toList . )` $ (,) <$> s1 <*> s2) >>= print where s1 = pure 1 <> pure 2 s2 = pure 3 <> pure 4  [(1,3),(2,4)] WThis applicative operation can be seen as the zipping equivalent of interleaving with 1.Like  but runs all@ iterations fairly concurrently using a round robin scheduling. import Streamly# import Control.Concurrent main = . $ do n <- return 3 <> return 2 <> return 1 liftIO $ do threadDelay (n * 1000000) myThreadId >>= \tid -> putStrLn (show tid ++ ": Delay " ++ show n)  ?ThreadId 40: Delay 1 ThreadId 39: Delay 2 ThreadId 38: Delay 3 Unlike L all iterations are guaranteed to run fairly concurrently, unconditionally.Like  but may run each iteration concurrently using demand driven concurrency. More concurrent iterations are started only if the previous iterations are not able to produce enough output for the consumer. import Streamly# import Control.Concurrent main = - $ do n <- return 3 <> return 2 <> return 1 liftIO $ do threadDelay (n * 1000000) myThreadId >>= \tid -> putStrLn (show tid ++ ": Delay " ++ show n)  ?ThreadId 40: Delay 1 ThreadId 39: Delay 2 ThreadId 38: Delay 3 ?All iterations may run in the same thread if they do not block.Like  but different in nesting behavior. It fairly interleaves the iterations of the inner and the outer loop, nesting loops in a breadth first manner. main = ,\ $ do x <- return 1 <> return 2 y <- return 3 <> return 4 liftIO $ print (x, y) (1,3) (2,3) (1,4) (2,4) The  instance of  runs the monadic continuation+ for each element of the stream, serially. main = +9 $ do x <- return 1 <> return 2 liftIO $ print x  1 2 0 nests streams serially in a depth first manner. main = +\ $ do x <- return 1 <> return 2 y <- return 3 <> return 4 liftIO $ print (x, y)  (1,3) (1,4) (2,3) (2,4) This behavior is exactly like a list transformer. We call the monadic code being run for each element of the stream a monadic continuation. In imperative paradigm we can think of this composition as nested forp loops and the monadic continuation is the body of the loop. The loop iterates for all elements of the stream.DClass of types that can represent a stream of elements of some type a in some monad m.&Add an element a the head of a stream.An empty stream.Build a stream from its church encoding. The function passed maps directly to the underlying representation of the stream type. The second parameter to the function is the "yield" function yielding a value and the remaining stream if any otherwise 9. The third parameter is to represent an "empty" stream.2Build a singleton stream from a callback function.Read an SVar to get a stream.Fold a stream using its church encoding. The second argument is the "step" function consuming an element and the remaining stream, if any. The third argument is for consuming an "empty" stream that yields nothing. 1Run a streaming composition, discard the results.Write a stream to an lQ in a non-blocking manner. The stream can then be read back from the SVar using .!EMake a stream asynchronous, triggers the computation and returns a stream in the underlying monad representing the output generated by the original computation. The returned action is exhaustible and must be drained once. If not drained fully we may have a thread blocked forever and once exhausted it will always return  ."7Zip two streams serially using a pure zipping function.#xZip two streams asyncly (i.e. both the elements being zipped are generated concurrently) using a pure zipping function.$$Adapt one streaming type to another.%)Interpret an ambiguously typed stream as .&)Interpret an ambiguously typed stream as .')Interpret an ambiguously typed stream as .()Interpret an ambiguously typed stream as .))Interpret an ambiguously typed stream as .*)Interpret an ambiguously typed stream as .+Same as runStreaming . serially.,Same as runStreaming . interleaving.-Same as runStreaming . asyncly..Same as runStreaming . parallely./Same as runStreaming . zipping.0Same as runStreaming . zippingAsync.13Sequential interleaved composition, in contrast to } this operator fairly interleaves two streams instead of appending them; yielding one element from each stream alternately. main = (toList . %@ $ (return 1 <> return 2) <=> (return 3 <> return 4)) >>= print   [1,3,2,4] !This operator corresponds to the  style. Unlike , this operator cannot be used to fold infinite containers since that might accumulate too many partially drained streams. To be clear, it can combine infinite streams but not infinite number of streams.25Demand driven concurrent composition. In contrast to  > this operator concurrently "merges" streams in a left biased manner rather than fairly interleaving them. It keeps yielding from the stream on the left as long as it can. If the left stream blocks or cannot keep up with the pace of the consumer it can concurrently yield from the stream on the right in parallel. main = (toList . %? $ (return 1 <> return 2) <| (return 3 <> return 4)) >>= print   [1,2,3,4] Unlike  Z it can be used to fold infinite containers of streams. This operator corresponds to the $ type for product style composition.3 Like the Prelude foldj but allows you to specify a binary sum style stream composition operator to fold a container of streams. !foldWith (<>) $ map return [1..3]4Like  but allows you to specify a binary sum style composition operator to fold a container of streams. Maps a monadic streaming action on the container before folding it. foldMapWith (<>) return [1..3]5Like 4d but with the last two arguments reversed i.e. the monadic streaming function is the last argument.[ !"#$%&'()*+,-./0123451lopqt !"#$%&'()*+,-./012345M !"#$%&'()*+,-./01234515(c) 2017 Harendra KumarBSD3harendra.kumar@gmail.com experimentalGHCNone /9:;<=IOT 6<Build a Stream by unfolding pure steps starting from a seed.7?Build a Stream by unfolding monadic steps starting from a seed.8Same as  foldWith (<>) but more efficient.96Read lines from an IO Handle into a stream of Strings.: Right fold.;.Right fold with a monadic step function. See @ for an example use.<VStrict left fold. This is typed to work with the foldl package. To use directly pass  as the third argument.=rStrict left fold, with monadic step function. This is typed to work with the foldl package. To use directly pass  as the third argument.>LDecompose a stream into its head and tail. If the stream is empty, returns <. If the stream is non-empty, returns 'Just (a, ma)', where a is the head of the stream and ma its tail.?*Write a stream of Strings to an IO Handle.@5Convert a stream into a list in the underlying monad.A Take first n/ elements from the stream and discard the rest.B2Include only those elements that pass a predicate.C<End the stream as soon as the predicate fails on an element.DDiscard first n, elements from the stream and take the rest.EdDrop elements in the stream as long as the predicate succeeds and then take the rest of the stream.F?Determine whether all elements of a stream satisfy a predicate.GFDetermine whether any of the elements of a stream satisfy a predicate.H8Determine the sum of all elements of a stream of numbersI<Determine the product of all elements of a stream of numbersJ0Extract the first element of the stream, if any.K/Extract the last element of the stream, if any.L6Determine whether an element is present in the stream.M:Determine whether an element is not present in the stream.N#Determine the length of the stream.O*Determine the minimum element in a stream.P*Determine the maximum element in a stream.Q_Replace each element of the stream with the result of a monadic action applied on the element.R[Apply a monadic action to each element of the stream and discard the output of the action.SOReduce a stream of monadic actions to a stream of the output of those actions.T:Zip two streams serially using a monadic zipping function.U{Zip two streams asyncly (i.e. both the elements being zipped are generated concurrently) using a monadic zipping function. 6789:;<=>?@ABCDEFGHIJKLMNOPQRSTU$"#6789:;<=>?@ABCDEFGHIJKLMNOPQRSTU$6789:;<=>@?FGHIJKNLMPOBACDEQRS"T#U 6789:;<=>?@ABCDEFGHIJKLMNOPQRSTU(c) 2017 Harendra KumarBSD3harendra.kumar@gmail.com experimentalGHCNone0   !$%&'()*+,-./012345112!%&'()*$ +,-./0345   (c) 2017 Harendra KumarBSD3harendra.kumar@gmail.comNoneNone:VWXYZ[\]VYWXZ[\]VWXYZ[\]VWXYZ[\]None_`abcd_`abcd_`abcd_`abcdNone:eeeeNone:fghifghifghifghiNonejjjj (c) 2017 Harendra KumarBSD3harendra.kumar@gmail.com experimentalGHCNone]deij]deij                 ! "#$%#$&'( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G HIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} ~      ~           * + , - . / %streamly-0.1.0-Kbk6VyWXErl1a2LX8HU0ztStreamly Streamly.TimeStreamly.PreludeStreamly.Examples.AcidRainGame Streamly.Examples.CirclingSquare"Streamly.Examples.ListDirRecursive$Streamly.Examples.MergeSortedStreams#Streamly.Examples.SearchEngineQuery Streamly.CoreStreamly.StreamsStreamly.TutorialStreamly.ExamplesbaseData.Semigroup<>GHC.Basememptymappendmconcat SemigroupMonoidstimessconcatControl.Monad.IO.ClassliftIOMonadIOmanysome<|>empty Alternativemplusmzero MonadPlustransformers-0.5.2.0Control.Monad.Trans.Classlift MonadTransperiodic withClock MonadAsyncZipAsync ZipStream ParallelTAsyncT InterleavedTStreamT Streamingconsnil runStreamingasynczipWith zipAsyncWithadaptserially interleavingasyncly parallelyzipping zippingAsync runStreamTrunInterleavedT runAsyncT runParallelT runZipStream runZipAsync<=><|foldWith foldMapWith forEachWithunfoldrunfoldrMeach fromHandlefoldrfoldrMfoldlfoldlMunconstoHandletoListtakefilter takeWhiledrop dropWhileallanysumproductheadlastelemnotElemlengthminimummaximummapMmapM_sequencezipWithM zipAsyncWithMEventHarmHealQuit userActionacidRaingame acidRainGame $fShowEventsdlInitdisplay refreshRateupdateController updateDisplaycirclingSquarelistDirRecursive getSorted mergeAsyncmergemergeSortedStreamssearchEngineQueryStreamSVar fromStreamVarjoinStreamVar2 SVarStyle SVarSchedSVarTag ChildEvent interleave newEmptySVar newStreamVar1 newStreamVar2 toStreamVarparAltparLeft$fAlternativeStream$fSemigroupStream runStream outputQueuedoorBellenqueuerunqueuerunningThreads queueEmpty svarStyleLIFOFIFO Conjunction Disjunction ChildYield ChildStopsconssnildoForksendsendStop enqueueLIFO runqueueLIFO enqueueFIFO runqueueFIFO addThread delThreadallThreadsDonehandleChildException pushWorkersendWorkerWait getFifoSVar getLifoSVar withNewSVar2$fMonadStatesStream$fMonadReaderrStream$fMonadErroreStream$fMonadThrowStream$fMonadIOStream$fMonadBasebStream$fMonadTransStream$fMonadPlusStream $fMonadStream$fApplicativeStream$fFunctorStream$fMonoidStreamMonad streamBuildNothing fromCallbackfromSVar streamFoldtoSVar Data.FoldablefoldMap getZipAsync getZipStream getParallelT getAsyncTgetInterleavedT getStreamTtoStream fromStreamparbind$fFloatingZipAsync$fFractionalZipAsync $fNumZipAsync$fStreamingZipAsync$fApplicativeZipAsync$fFunctorZipAsync$fFloatingZipStream$fFractionalZipStream$fNumZipStream$fStreamingZipStream$fApplicativeZipStream$fFunctorZipStream$fFloatingParallelT$fFractionalParallelT$fNumParallelT$fFunctorParallelT$fApplicativeParallelT$fMonadParallelT$fStreamingParallelT$fFloatingAsyncT$fFractionalAsyncT $fNumAsyncT$fFunctorAsyncT$fApplicativeAsyncT $fMonadAsyncT$fStreamingAsyncT$fFloatingInterleavedT$fFractionalInterleavedT$fNumInterleavedT$fFunctorInterleavedT$fApplicativeInterleavedT$fMonadInterleavedT$fStreamingInterleavedT$fFloatingStreamT$fFractionalStreamT $fNumStreamT$fFunctorStreamT$fApplicativeStreamT$fMonadStreamT$fStreamingStreamTid