śĪ!‘ †¶      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc d e f g h i j k l m n o p q r s t u v w x y z { | } ~  €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž   ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ   ” ¢ £ ¤ „ ¦ § Ø © Ŗ « ¬ ­ ® ư±²³“µNone =>?@AHSVXboxba Committer a "commits" values of type a. A Sink and a Consumer are some other metaphors for this. A Committer absorbsq the value being committed; the value disappears into the opaque thing that is a Committer from the pov of usage.boxlift a committer from STMboxUThis is a contramapMaybe, if such a thing existed, as the contravariant version of a ¶. See .https://hackage.haskell.org/package/witherable witherablebox prism handlerboxboxSafe=>?@ASX÷ box.sometimes you have no choice but to void it upboxA continuation similar to ContT9 but where the result type is swallowed by an existential  None =>?@AHSVX8boxan 5 "emits" values of type a. A Source & a Producer (of aDs) are the two other alternative but overloaded metaphors out there.¢An Emitter 'reaches into itself' for the value to emit, where itself is an opaque thing from the pov of usage. An Emitter is named for its main action: it emits.!boxlike a monadic mapMaybe. (See  .https://hackage.haskell.org/package/witherable witherable)"box prism handler#boxattoparsec parse emitter$boxread parse emitter"boxbox !"#$ !"$#None =>?@AHSVX'°,box’ķA Box is a product of a Committer m and an Emitter. Think of a box with an incoming wire and an outgoing wire. Now notice that the abstraction is reversable: are you looking at two wires from "inside a box"; a blind erlang grunt communicating with the outside world via the two thin wires, or are you looking from "outside the box"; interacting with a black box object. Either way, it's a box. And either way, the committer is contravariant and the emitter covariant so it forms a profunctor.a Box can also be seen as having an input tape and output tape, thus available for turing and finite-state machine metaphorics.0boxlift a box from STM1boxa profunctor dimapMaybe,-./01,-./01None =>?@AHSVX8Ģ5box5" specifies how messages are queued<box"create a queue, returning the ends·box#write to a queue, checking the sealøbox*read from a queue, and retry if not sealed¹box$turn a queue into a box (and a seal)ŗbox#write to a queue, checking the seal»box*read from a queue, and retry if not sealed>box5wait for the first action, and then cancel the second¼box[connect a committer and emitter action via spawning a queue, and wait for both to complete.½box[connect a committer and emitter action via spawning a queue, and wait for both to complete.¾box[connect a committer and emitter action via spawning a queue, and wait for both to complete.?boxcreate an unbounded queue@box7create an unbounded queue, returning the emitter resultAbox9create an unbounded queue, returning the committer resultBbox7create an unbounded queue, returning the emitter resultCbox7create an unbounded queue, returning the emitter resultDbox7create an unbounded queue, returning the emitter resultEbox9create an unbounded queue, returning the committer result578;69:<=>?@ABCDE578;69:?A@BCED>=<None =>?@AHSVXA°FboxDhook an emitter action to a queue, creating a committer continuationGboxDhook a committer action to a queue, creating an emitter continuationHboxDhook a committer action to a queue, creating an emitter continuationIboxcreate a double-queued box plugJboxėcreate a box plug from a box action. Caution: implicitly, this (has to) forget interactions between emitter and committer in the one action (and it does so silently). These forgotten interactions are typically those that create racesFGHIJFGHIJNone =>?@AHSVXPjKbox'fuse an emitter directly to a committerLboxslightly more efficient versionMbox fuse a box L(fuse (pure . Just) $ liftB <$> (Box <$> cStdout 2 <*> emitter')) >> sleep 1hi bye 9etc () (Transducer id) == fuse (pure . pure) . fmap liftBNbox&fuse a box with an STM mapMaybe actionOboxfuse-branch an emitterPboxfuse a committer to a bufferQboxfuse an emitter to a bufferRboxfuse an emitter to a bufferSboxmerge two emittersĮThis differs from `liftA2 (<>)` in that the monoidal (and alternative) instance of an Emitter is left-biased (The left emitter exhausts before the right one is begun). This merge is concurrent.Tboxmonadic versionUboxmerge two committers not workingVbox<a failed attempt to understand the either continuation styleWbox5a box modifier that feeds commits back to the emitterXboxOan emitter post-processor that cons transformed emissions back into the emitterKLMNOPQRSTUVWXKLMNOWXQRPSTUVNoneSœYbox a funneler\boxa broadcaster _box!create a (broadcaster, committer)`boxsubscribe to a broadcasteraboxcreate a (funneler, emitter)bboxwiden to a funneler YZ[\]^_`ab \]^_`YZ[ab None =>?@AHSVXZT cbox)create a committer from a stream consumerdboxcreate a committer from a foldeboxcreate a committer from a sinkfboxcreate an emitter from a streamgboxIinsert a queue into a stream (left biased collapse) todo: look at biaseshboxturn an emitter into a streamiboxturn an emitter into a streamjboxturn a stream into a committerkboxturn a stream into a committer cdefghijk hjcdefgik None.>SX` pboxsleep for x secondsqbox9keeping a box open sometimes needs a long running emitterrboxa stream with suggested delays. DiffTime is the length of time to wait since the start of the stream > delayTimed (S.each (zip (fromIntegral  $ [1..10]) [1..10])) |> S.printtbox3adding a time stamp todo: how to do this properly? lmnopqrst pqrlmnost None =>?@AHSVXm\xboxtransduction  (https://en.wikipedia.org/wiki/Transducerwiki“ says: "A transducer is a device that converts energy from one form to another." Translated to context, this Transducer converts a stream of type a to a stream of a different type.{boxconvert a Pipe to a Transducer|boxemit - transduce - commitXwith etc, you're in the box, and inside the box, there are no effects: just a stream of aØs, pure functions and state tracking. It's a nice way to code, and very friendly for the compiler. When the committing and emitting is done, the box collapses to state.€The combination of an input tape, an output tape, and a state-based stream computation lends itself to the etc computation as a  5https://en.wikipedia.org/wiki/Finite-state_transducerfinite-state transducer or mealy machine.xyz{|}xyz|}{ None =>?@AHSVXyŹboxa single stdin committer action€boxa finite stdin committer actionbox a forever stdin committer action‚boxa Cont stdin emitterƒbox,read from console, throwing away read errors„boxa single stdout emitter actionæboxa single stdout emitter action…boxa finite stdout emitter action†boxa finite stdout emitter action‡boxa forever stdout emitter actionˆboxa Cont stdout committer‰boxshow to stdoutŠbox^console box > etc () (Trans $ s -> s & S.takeWhile (/="q") & S.map ("echo: " <>)) (console 5)‹boxemit lines from a fileŒboxcommit lines to a fileboxcommit to a list CRefŽboxcommit to a monoidal CRefbox<fold an emitter through a transduction, committing to a listboxget all commissions as a list‘boxget all emissions€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘None =>?@AHSVXzųi  !"#$,-./01578;69:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXcdefghijklmnopqrstxyz{|}€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘ None 27=>?SX€²¤boxan effect that can be started and stopped committer is an existence test controlBox :: (MonadConc m) => ControlConfig -> m () -> ControlBox m¦boxLsend Start, wait for a Ready signal, run action, wait x secs, then send Quit’“”•–˜—™š›œžŸ ”¢£¤„¦§–˜—™š›œžŸ •’“””¢£¤„¦§NoneESX…{ÆboxZAn updater of a value a, where the updating process consists of an IO fold over an emitter±box Create an  Updatable value using a pure Ą²box^run an action on each update > listen mempty = id > > listen (f <> g) = listen g . listen fư±²³ư±²³Safe…įĮĀĆÄÅĘĒČÉ !"#$%&'()*++,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcddeffghijk l m n o p q r s t u u v w x y z { | } ~  € €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž   ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ   ” ¢ £ ¤ „ ¦ § Ø © Ŗ « ¬ ­ ® Æ ° ± ² ³ “ µ¶¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘ ĒČÉŹĖĢĶĪĻŠŃŅÓ"box-0.0.1.5-20i6lBtrzQS4oHqC1d1Lmo Box.CommitterBox.Cont Box.EmitterBox.Box Box.Queue Box.PlugsBox.Connectors Box.Broadcast Box.StreamBox.TimeBox.TransducerBox.IO Box.Control Box.UpdaterBox Paths_box CommittercommitliftCcmaphandles$fDecidableCommitter$fDivisibleCommitter$fContravariantCommitter$fMonoidCommitter$fSemigroupCommitterCont_with_Contwith $fMonoidCont$fSemigroupCont $fMonadIOCont $fMonadCont$fApplicativeCont $fFunctorCont $fMonoidCont_$fSemigroupCont_$fMonadIOCont_ $fMonadCont_$fApplicativeCont_$fFunctorCont_EmitteremitliftEemapkeepseParseeRead$fMonoidEmitter$fSemigroupEmitter$fMonadPlusEmitter$fAlternativeEmitter$fMonadEmitter$fApplicativeEmitter$fFunctorEmitter committeremitterliftBbmap $fMonoidBox$fSemigroupBox$fProfunctorBoxQueue UnboundedBoundedSingleLatestNewestNewendstoBoxLog waitCancelqueuequeueEqueueCqueueCMqueueEM queueELog queueCLog commitPlugemitPlug emitPlugMboxPlug boxForgetPlugfuse_fuseSTM_fusefuseSTMforkEmit fuseCommitfuseEmit fuseEmitMemergeemergeM splitCommit contCommitfeedback feedbackEFunnelerunFunnel Broadcaster unBroadcast broadcast subscribefunnelwidentoCommit toCommitFold toCommitSinktoEmit queueStreamtoStream toStreamM fromStream fromStreamMStamped timestampvaluesleepkeepOpen delayTimedstampNow emitStamp $fEqStamped $fShowStamped $fReadStamped Transducer transduceasPipeetcetcM$fCategoryTYPETransducercStdin_cStdincStdin'eStdin readStdineStdout_eStdouteStdoutMeStdout'cStdout showStdout consolePlug emitLines commitLinescCRefcCRefMtoListMgetCommissions getEmissions ControlConfig KeepAlive AllowDeath ControlBox ControlCommReadyCheckDiedStopKillShutDownStartResetOnLogdefaultControlConfigconsoleControlBoxparseControlComms controlBox runControlBoxtestBoxtimeOut$fShowControlComm$fReadControlComm$fEqControlComm$fDataControlComm$fGenericControlComm$fShowControlConfig$fEqControlConfigUpdaterupdaterlistenupdates$fApplicativeUpdater$fFunctorUpdaterbase Data.MaybemapMaybe writeCheck readChecktoBox writeCheckLog readCheckLogwithQwithQM withQMLog eStdoutM_"foldl-1.4.5-LJ0a2YZuFPWGh5PU96gyOu Control.FoldlFoldversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName