Arrow based stream transducers

Latest on Hackage:4.0.1

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow to host generated Haddocks.

BSD3 licensed by Hidenori Azuma
Maintained by Hidenori Azuma


Arrow based stream transducer.


As other iteratee or pipe libraries, machinecell abstracts general iteration processes.

Here is an example that is a simple iteration over a list.

>>> run (evMap (+1)) [1, 2, 3]
[2, 3, 4]

In above statement, "evMap (+1)" has a type "ProcessA (->) (Event Int) (Event Int)", which denotes "A stream transducer that takes a series of Int as input, gives a series of Int as output, run on base arrow (->)."

In addition to this simple iteration, machinecell has following features.

  • Side effects
  • Composite pipelines
  • Arrow compositions
  • Behaviours and switches

See Control.Arrow.Machine documentation.

Comparison to other libraries.

Some part of machinecell is similar to other stream transducer libraries, namely pipes, conduit, or machines. machinecell can be seen as a restricted variation of them to one-directional. But additionally, machinecell supports arrow compositions. Bidirectional communications can be taken place by ArrowLoop feature.

Rather, there are several other arrowised stream transducer libraries. streamproc shares the most concept to machinecell. But actually it has a problem described later in this post. Machinecell can be said as "Streamproc done right."

auto is a brand-new arrowised stream transducer library. Compared to it, machinecell's advantage is await/yield coroutines, while auto's one is serialization.

Motivation and background

"Generalizing monads to arrows," The original paper of arrow calculation mentions a kind of stream transducer, which later implemented as streamproc.

And other people propose instance declarations of Arrow class for several existing stream processors.

But actually, there is a problem argued in this post.

The core problem is, while arrow uses tuples as parallel data stream, they cannot represent a composite streams if they carry different numbers of data in parallel.

To solve this problem, some arrow libraries restrict transducers to one-to-one data transformation. Yampa and netwire does so, as mentioned in above post. And auto also takes this approach.

Machinecell's approach is different, but simple too. The key idea is wrapping all types of data stream into a maybe-like type. Then even tuples can represent different numbers of data, by inserting appropreate number of 'Nothing's.

Furthermore, I identified the maybe-like type as the 'Event' type, which appears in Yampa and netwire. Then I successively implemented several arrows of Yampa and netwire.

API names come from stream libraries are named after machines', while ones from FRPs are after Yampa's. Now, machinecell may be seen as a hybrid of machines and Yampa.



Breaking changes of APIs

  • Side-effects are represented by Monads rather than ArrowApplyies.
    • Replace the base arrow ProcessA with ProcessT
    • ProcessA is now type alias for compatibility
    • Change the signatures of construction functions
      • constructT, repeatedlyT
      • construct, repeatedly
    • Change the signatures of running functions
      • runT, runT_, run, run_
      • stepRun, stepYield
        • Delete ExecInfo.
  • Change the Occasional' type class
    • Add method burst
    • Move noEvent end out of the type class
  • Delete echo. Use id instead.


  • Add ZeroEvent. Change the signatures of blocking sources with it.
  • Add Evolution
  • Add type classes MonadAwait, MonadYield, MonadStop
    • Generalize await, yield, and stop to Evolution
  • Add fire, fire0


  • Modify again the versions of depending packages.
  • Make the default of 'arrow-tr' flag False.


  • Modify the versions of depending packages.


  • Correct a space leak problem
  • Add splitEvent, oneshot
  • Generalize some functions
    • construct, repeatedly
    • filterEvent, filterJust, filterLeft, filterRight


  • Add arrow-tr flag
  • add gSwitch, dgSwitch


  • Add Discrete utilities
    • eval
    • refer
    • kSwitch
    • dkSwitch
    • Num instance definition
  • Add source utilities
    • blockingSource
    • interleave
    • blocking
  • Delete sample
  • Change a switching behavior. With previous implementation, a switching doesn't occur when a runnning transducer emits a trigger event using now transducer.


  • Fix performance issue of switch, dSwitch, accum, dAccum.


  • ArrowLoop instance now independent of base arrow's
  • Make PlanT newtype and add stop handling MonadPlus instance
  • API changes
    • Added filterJust, filterLeft, filterRight
    • Deleted Show and Eq instance of Event type
    • Added Isos of ArrowUtil module
    • Delete state monad handling.
    • Delete unsafe primitives cycleDelay, fitEx, unsafeSteady, loop'
    • Delete deperecated passRecent, withRecent
    • Delete ProcessA ArrowReader instance and added readerProc


  • Added dHold, dAccum.
  • Deprecated cycleDelay.
  • Fixed muted.
  • Slightly changed the ArrowLoop instance declaration.
    • Right tightening rule will be preserved.
    • For IO processes, "Indefinite access to MVar" errors, which used to occur in some situations in old versions, will be suppressed.
    • This will not change any existing code unless it loops back any Event-type signal.


  • Support free-4.12


  • Relocate files
    • catch and its families are moved to Misc.Exception
  • Performance improve
  • Added primitives: fitEx, unsafeSteady, unsafeExhaust
  • Added: condEvent, filterEvent, muted
  • Added to Misc: Discrete, Pump.asUpdater, Pump.Alg
  • Deleted deprecated: hEv, hEv', evMaybe, fromEvent, split, join, split2, join2, feedback, feedback1, isNoEvent, isOccasional, isEnd
  • Deleted Foldable and Traversable instance of Event.
  • Added Occasional' by splitting some members from Occasional


  • (Fix test suite of 1.3.0)


  • Support of ArrowState.
  • Added utilities related to ArrowLoop (cycleDelay, Pump)
  • Correct EOS behaviour of some utilities.


  • Support of ArrowReader.
  • Added await fail handling.
  • Improved performance by church-encoded free monads.
  • Arrow stack of newest GHC support for some utilities.


  • Eliminated banana brackets to support newest GHC.


  • Hide Event constructors and some instances (Applicative, Monad).
  • Added feedback
  • Fixed accum


  • Fix some bugs of core part.
  • Added onEnd.
  • Added sample.


  • First release.
Depends on 6 packages:
Used by 1 package:
comments powered byDisqus