śĪ!·"ŖxŽ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcde f g h i j k l m n o p q r s t u v w x y z { | } ~  €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž   ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ   ” ¢ £ ¤ „¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻNone =>?@AHSVX&boxba Committer a "commits" values of type a. A Sink and a Consumer are some other metaphors for this.„A Committer absorbs the value being committed; the value disappears into the opaque thing that is a Committer from the pov of usage.boxlift a committer from STMboxdThis is a contramapMaybe, if such a thing existed, as the contravariant version of a mapMaybe. See .https://hackage.haskell.org/package/witherable witherablebox prism handlerboxboxSafe=>?@ASXL box.sometimes you have no choice but to void it upboxiA continuation similar to ` Control.Monad.ContT` but where the result type is swallowed by an existential  None =>?@AHSVXģboxan { "emits" values of type a. A Source & a Producer (of a's) 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.!boxlift an STM emitter"boxlike a monadic mapMaybe. (See  .https://hackage.haskell.org/package/witherable witherable)#box prism handler$boxattoparsec parse emitter%boxread parse emitter#boxbox !"#$% !"#%$None =>?@AHSVX*d-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.1boxlift a box from STM2boxa profunctor dimapMaybe-./012-./012None =>?@AHSVXB6box6" 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)?box5wait for the first action, and then cancel the second@boxErun two actions concurrently, but wait and return on the left result.AboxFrun two actions concurrently, but wait and return on the right result.Bbox[connect a committer and emitter action via spawning a queue, and wait for both to complete.Cbox`connect a committer and emitter action via spawning a queue, and wait for committer to complete.Dbox^connect a committer and emitter action via spawning a queue, and wait for emitter 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.ābox[connect a committer and emitter action via spawning a queue, and wait for both to complete.Eboxcreate an unbounded queueFbox7create an unbounded queue, returning the emitter resultHbox9create an unbounded queue, returning the committer resultIbox9create an unbounded queue, returning the committer resultJbox7create an unbounded queue, returning the emitter resultKbox7create an unbounded queue, returning the emitter resultLbox7create an unbounded queue, returning the emitter resultMbox7create an unbounded queue, returning the emitter result689<7:;=>?@ABCDEFGHIJKLM689<7:;EHIFGJKLM?=BDC>@ANone =>?@AHSVXK,NboxDhook an emitter action to a queue, creating a committer continuationOboxDhook a committer action to a queue, creating an emitter continuationPboxDhook a committer action to a queue, creating an emitter continuationQboxcreate a double-queued box plugRboxė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 racesNOPQRNOPQRNone =>?@AHSVX[ Sbox'fuse an emitter directly to a committerTboxslightly more efficient versionUbox fuse a box L(fuse (pure . Just) $ liftB <$> (Box <$> cStdout 2 <*> emitter')) >> sleep 1hi bye 9etc () (Transducer id) == fuse (pure . pure) . fmap liftBVbox&fuse a box with an STM mapMaybe actionWboxfuse-branch an emitterXboxfuse a committer to a bufferYboxfuse a committer to a bufferZboxfuse an emitter to a buffer[boxfuse an emitter to a buffer\boxmerge 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.]boxmonadic version^boxsplit a committer (STM m)_boxsplit a committer`boxuse a split committerabox5a box modifier that feeds commits back to the emitterbboxOan emitter post-processor that cons transformed emissions back into the emittercboxturn a list into an emitterdboxturn a list into an emitterSTUVWXYZ[\]^_`abcdSTUVWabZ[XY\]_^`cd None^Xebox a funnelerhbox a broadcasterkbox!create a (broadcaster, committer)lboxsubscribe to a broadcastermboxcreate a (funneler, emitter)nboxwiden to a funneler efghijklmn hijklefgmn None =>?@AHSVXe obox)create a committer from a stream consumerpboxcreate a committer from a foldqboxcreate a committer from a sinkrboxcreate an emitter from a streamsboxIinsert a queue into a stream (left biased collapse) todo: look at biasestboxturn an emitter into a streamuboxturn an emitter into a streamvboxturn a stream into a committerwboxturn a stream into a committer opqrstuvw tvopqrsuw None.>SXkÕxbox$A value with a timestamp annotation.|boxsleep for x seconds}box9keeping a box open sometimes needs a long running emitter~box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.printboxAdd the current time€box3adding a time stamp todo: how to do this properly? xyz{|}~€ |}~xyz{€ None =>?@AHSVXy—„boxtransduction  (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 - commit’with 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.‰boxMonadic version of etc.„…†‡ˆ‰„…†ˆ‰‡ None =>?@AHSVX‰™‹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•boxa Cont stdout committer–boxa Cont stdin emitter—boxshow to stdoutäbox Get a single line from a handle.˜box Get lines from a handle forever.åboxPut a single line to a handle.™box"a forever getLine committer actionšbox^console box > etc () (Trans $ s -> s & S.takeWhile (/="q") & S.map ("echo: " <>)) (console 5)›box"Emits lines of Text from a handle.œbox!Commit lines of Text to a handle. 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 =>?@AHSVXŠ’†  !"#$%-./012689<7:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€„…†‡ˆ‰‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤None 27=>?SX¤Š„box§box maximum number of starts allowedØboxwhether to start automatically©box0whether to rerun with a delay if the action diesŖboxlogging debug Info«boxA - that communicates via “ and ­ or an underlying typed-channel¬boxA - that only communicates via “ and ­­box response ADT“box request ADTŗboxParse command line requests»box6Default is one start, manual start and no autorestart.¼boxa command-line control box.½boxa command-line control box.¾boxPan effect that can be started, stopped and restarted (a limited number of times)æboxPan effect that can be started, stopped and restarted (a limited number of times)Įboxaction for testingĀbox!A box with a self-destruct timer.Ćbox+a canned ControlRequest emitter with delaysÄboxmanual testing > testBoxManual (ControlConfig 1 True (Just 0.5) False) 2.3 (beep 3 1 0.5) Status (On,0) beep 1 beep 2 beep 3 Left ShutDownÅbox’‘auto testing FIXME: Doesn't work with doctest > testBoxAuto (ControlConfig 5 True (Just 0.2) False) 5 [(Check, 0.1), (Start,0.1), (Stop,1), (Start, 0.1), (Check, 0.1), (Reset,0.1)] (beep 2 1 1) Left (Status (On,5)) Left (Status (On,4)) Left (Status (On,4)) beep 1 Left (Status (Off,4)) Left (Status (On,4)) Left (Status (On,3)) Left (Status (On,2)) beep 1 beep 2 beep 1 Left ShuttingDown£testBoxAuto (ControlConfig 1 True (Just 0.5) False) 3 [(Reset,1.1), (Quit, 1)] (beep 3 1 1) Left (Status (On,1)) beep 1 Left ShuttingDown Left (Status (On,-1))"„¦§Ø©Ŗ«¬­°®Æ±²³“µ¹¶·øŗ»¼½¾æĄĮĀĆÄÅĘ"“µ¹¶·ø­°®Æ±²³«¬„¦§Ø©Ŗ»¼½ŗ¾æĄÄÅĮĀĆĘNoneESXŖL×boxZAn updater of a value a, where the updating process consists of an IO fold over an emitterŁbox Create an × value using a pure ęŚbox^run an action on each update > listen mempty = id > > listen (f <> g) = listen g . listen fŪbox Convert an × to an Emitter continuation.×ŲŁŚŪ×ŲŁŚŪē !"#$%&'()*+,--./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnop q q r s s t u v w x y z { | } ~  €  ‚ ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ   Ž   ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ   ” ¢ £ ¤ „ ¦ § Ø © Ŗ « ¬­­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽŽßąįāćäåęēč é ź ėģķīļbox-0.4.0-9uzoOHquWyV3T7MIf5USXBox Box.CommitterBox.Cont Box.EmitterBox.Box Box.Queue Box.PlugsBox.Connectors Box.Broadcast Box.StreamBox.TimeBox.TransducerBox.IO Box.Control Box.Updaterbase Data.Function& 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 UnboundedBoundedSingleLatestNewestNewendstoBox waitCancelconcurrentlyLeftconcurrentlyRightwithQwithQCwithQEqueuequeueEqueueE'queueCqueueC'queueCMqueueCM'queueEMqueueEM' commitPlugemitPlug emitPlugMboxPlug boxForgetPlugfuse_fuseSTM_fusefuseSTMforkEmit fuseCommit fuseCommitMfuseEmit fuseEmitMemergeemergeMsplitCommitSTM splitCommit contCommitfeedback feedbackE fromListEtoListEFunnelerunFunnel Broadcaster unBroadcast broadcast subscribefunnelwidentoCommit toCommitFold toCommitSinktoEmit queueStreamtoStream toStreamM fromStream fromStreamMStamped timestampvaluesleepkeepOpen delayTimedstampNow emitStamp $fEqStamped $fShowStamped $fReadStamped Transducer transduceasPipeetcetcM$fCategoryTYPETransducercStdin_cStdincStdin'eStdin readStdineStdout_eStdouteStdoutMeStdout'cStdoutcStdout'eStdin' showStdoutgetLineputLine consolePlug emitLines commitLines fileEmitter fileCommitterappendCommittercCRefcCRefMtoListMgetCommissions getEmissions ControlConfigstarts autoStart autoRestartdebug ControlBox ControlBox_ControlResponse ShuttingDownStatusInfoToggleOnOffControlRequestCheckStartStopResetQuitparseControlRequestdefaultControlConfigconsoleControlBoxconsoleControlBox_ controlBoxcontrolBoxProcesscontrolConsolebeeptimeOut timedRequests testBoxManual testBoxAutotestCatControl$fShowControlRequest$fReadControlRequest$fEqControlRequest$fDataControlRequest$fGenericControlRequest $fShowToggle $fReadToggle $fEqToggle$fGenericToggle$fShowControlResponse$fReadControlResponse$fEqControlResponse$fGenericControlResponse$fShowControlConfig$fEqControlConfig$fOrdControlConfigUpdaterupdaterlistenupdates$fApplicativeUpdater$fFunctorUpdater writeCheck readCheckwithQMwithQEMwithQCM eStdoutM_getLine_putLine_!foldl-1.4.6-6kFigdCLI8KusW6mJbYzf Control.FoldlFold