Until then, monads had proven sufficient for most problems requiring the combination of program logic in pure code.
As a relatively new concept, there is not a single, standard definition, but all formulations are logically equivalent, feature some required methods, and strictly obey certain mathematical laws.
One more helpful method can be derived from arr and first (and from which first can be derived): In addition to having some well-defined procedures, arrows must obey certain rules for any types they may be applied to: The remaining laws restrict how the piping method behaves when the order of a composition is reversed, also allowing for simplifying expressions: Arrows may be extended to fit specific situations by defining additional operations and restrictions.
Besides avoiding side effects, purely functional programming creates more opportunities for static code analysis.
They can also encourage code reuse by giving common linkages between program steps their own class definitions.
[6] Another issue, which applies to many functional programming constructs, is efficiently compiling code with arrows into the imperative style used by computer instruction sets.
Much of the utility of arrows is subsumed by more general classes like Profunctor (which requires only pre- and postcomposition with functions), which have application in optics.