## API - Combinators

Combinators compose new arrowlets from one or more arrowlets. The following arrowlets combinators are currently
available. Unary combinators are of the form *F*.`op`

(*[param]*), while binary combinators
are of the form

.*F*.op(*[param, ] G*)

Note that combinators are method calls which are evaluated from left to right.

(aliases:*F*.compose(*G*)`then`

,`next`

,`>>>`

)- Run
*F*, then*G*in sequence.

(aliases:*F*.product(*G*)`pair`

,`***`

)- Take as input
`Pair(`

, run*x*,*y*)*F*with the first component*x*and*G*with the second component*y*in parallel, and output the respective results as a pair tuple`Pair(`

.*xout*,*yout*) *F*.first()- Take as input
`Pair(`

, run*x*,*y*)*F*with the first component*x*, and output the result*xout*in a pair tuple with*y*,`Pair(`

.*xout*,*y*) - Equivalent to:

`var returnA = Arr(function(x) { return x; });`

return*F*.product(returnA) *F*.second()- Take as input
`Pair(`

, run*x*,*y*)*F*with the second component*y*, and output the result*yout*in a pair tuple with*x*,`Pair(`

.*x*,*yout*) - Equivalent to:

`var returnA = Arr(function(x) { return x; });`

return returnA.product(*F*)

(aliases:*F*.fanout(*G*)`split`

,`&&&`

)- Run
*F*and*G*with the same input*x*, and output the respective results as a pair tuple,`Pair(`

.*fx*,*gx*) - Equivalent to:

`var fanoutA = Arr(function(x) { return Pair(x, x) });`

return fanoutA.then(*F*.product(*G*)) *F*.bind(*G*)- Run
*F*with the input*x*, combine the output*fx*from*F*with the input*x*in a pair tuple,`Pair(`

, then run*x*,*fx*)*G*with the pair tuple as input, and output the result from*G*. - Equivalent to:

`var returnA = Arr(function(x) { return x; });`

return returnA.fanout(*F*).then(*G*) *F*.join(*G*)- Run
*F*with the input*x*, run*G*with the output*fx*from*F*, then output the result*gfx*from*G*with*fx*in a pair tuple,`Pair(`

.*fx*,*gfx*) - Equivalent to:

`var returnA = Arr(function(x) { return x; });`

return*F*.then(returnA.fanout(*G*)) *F*.repeat()- Run
*F*repeatedly in a loop.*F*should return`Repeat(`

to continue the loop, or*x*)`Done(`

to end the loop.*x*) *F*.animate(*[interval]*)- Like
`repeat`

, run*F*repeatedly in a loop, but at the event-loop update rate (typically 100Hz), optionally with a delay of`interval`

milliseconds between iterations.*F*should return`Repeat(`

to continue the loop, or*x*)`Done(`

to end the loop.*x*) *F*.or(*[eventname, ] G*)- Start both
*F*and*G*in parallel, allow only one, whichever progresses first, to continue to completion. This may be used to choose between two events, for example. *eventname*, if specified, gives the type of event that signals progress. By default, this is`"progress"`

, which is the event signaled by asynchronous arrowlets.