Arrow (computer science)

In computer science, arrows are a type class used in programming to describe computations in a pure and declarative fashion. First proposed by computer scientist John Hughes as a generalization of monads, arrows provide a referentially transparent way of expressing relationships between logical steps in a computation.[1] Unlike monads, arrows don't limit steps to having one and only one input. As a result, they have found use in functional reactive programming, point-free programming, and parsers among other applications.[1][2]

Motivation and history

While arrows were in use before being recognized as a distinct class, Hughes would publish their first definition in 2000. Until then, monads had proven sufficient for most problems requiring the combination of program logic in pure code. However, some useful libraries, such as the Fudgets library for graphical user interfaces and certain efficient parsers, defied rewriting in a monadic form.[1]

The formal concept of arrows was developed to explain these exceptions to monadic code, and in the process, monads themselves turned out to be a subset of arrows.[1] Since then, arrows have been an active area of research. Their underlying laws and operations have been refined several times, with recent formulations such as arrow calculus requiring only five laws.[3]

Relation to category theory

In category theory, the Kleisli categories of all monads form a proper subset of Hughes arrows.[1] While Freyd categories were believed to be equivalent to arrows for a time,[4] it has since been proven that arrows are even more general. In fact, arrows are not merely equivalent, but directly equal to enriched Freyd categories.[5]

Definition

Like all type classes, arrows can be thought of as a set of qualities that can be applied to any data type. In the Haskell programming language, arrows allow functions (represented in Haskell by an arrow symbol) to combine in a reified form. However, the actual term "arrow" may also come from the fact that some (but not all) arrows correspond to the morphisms (also known as "arrows" in category theory) of different Kleisli categories. 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.[6]

Functions

The description currently used by the Haskell standard libraries requires only two basic operations:

arr (s -> t)        ->   A s t
first (A s t)       ->   A (s,u) (t,u)

Although only these two procedures are strictly necessary to define an arrow, other methods can be derived to make arrows easier to work with in practice and theory. As all arrows are categories, they can inherit a third operation from the class of categories:

A s t  >>>  A t u   ->   A s u

One more helpful method can be derived from a combination of the previous three:

A s t  ***  A u v   ->   A (s,u) (t,v)

Arrow laws

In addition to having some well-defined procedures, arrows must obey certain rules for any types they may be applied to:

arr id              ==   id
arr (f >>> g)       ==   arr f  >>>  arr g
first (f >>> g)     ==   first f  >>>  first g
arr (first f)       ==   first (arr f)

The remaining laws restrict how the piping method behaves when the order of a composition is reversed, also allowing for simplifying expressions:

arr (id *** g)  >>>  first f       ==   first f  >>>  arr (id *** g)
first f  >>>  arr ((s,t) -> s)     ==   arr ((s,t) -> s)  >>>  f
first (first f)  >>>  arr ( ((s,t),u) -> (s,(t,u)) )   ==
  arr ( ((s,t),u) -> (s,(t,u)) )  >>>  first f

Applications

Arrows may be extended to fit specific situations by defining additional operations and restrictions. Commonly used versions include arrows with choice, which allow a computation to make conditional decisions, and arrows with feedback, which allow a step to take its own outputs as inputs. Another set of arrows, known as arrows with application, are rarely used in practice because they are actually equivalent to monads.[6]

Utility

Arrows have several benefits, mostly stemming from their ability to make program logic explicit yet concise. Besides avoiding side effects, purely functional programming creates more opportunities for static code analysis. This in turn can theoretically lead to better compiler optimizations, easier debugging, and features like syntax sugar.[6]

Although no program strictly requires arrows, they generalize away much of the dense function passing that pure, declarative code would otherwise require. They can also encourage code reuse by giving common linkages between program steps their own class definitions. The ability to apply to types generically also contributes to reusability and keeps interfaces simple.[6]

Arrows do have some disadvantages, including the initial effort of defining an arrow that satisfies the arrow laws. Because monads are usually easier to implement, and the extra features of arrows may be unnecessary, it is often preferable to use a monad.[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.

References

  1. 1.0 1.1 1.2 1.3 1.4 Hughes, John (May 2000). "Generalising Monads to Arrows" (PDF). Science of Computer Programming (Elsevier) 37 (1-3): 67–111. doi:10.1016/S0167-6423(99)00023-4. ISSN 0167-6423. Retrieved 10 June 2012.
  2. Paterson, Ross (27 March 2003). "Chapter 10: Arrows and Computation". In Gibbons, Jeremy; de Moor, Oege. The Fun of Programming (PS.GZ). Palgrave Macmillan. pp. 201–222. ISBN 978-1403907721. Retrieved 10 June 2012.
  3. Lindley, Sam; Wadler, Philip; Yallop, Jeremy (January 2010). "The Arrow Calculus" (PDF). Journal of Functional Programming 20 (1): 51–69. doi:10.1017/S095679680999027X. ISSN 0956-7968. Retrieved 10 June 2012.
  4. Jacobs, Bart; Heunen, Chris; Hasuo, Ichiro. "Categorical Semantics for Arrows". Journal of Functional Programming 19 (3-4): 403–438. doi:10.1017/S0956796809007308.
  5. Atkey, Robert (8 March 2011). "What is a Categorical Model of Arrows?" (PDF). Electronic Notes in Theoretical Computer Science (Elsevier) 229 (5): 19–37. doi:10.1016/j.entcs.2011.02.014. ISSN 1571-0661. Retrieved 10 June 2012.
  6. 6.0 6.1 6.2 6.3 6.4 Hughes, John (2005). "Programming with Arrows" (PDF). Advanced Functional Programming. 5th International Summer School on Advanced Functional Programming. 14–21 August 2004. Tartu, Estonia. Springer. pp. 73–129. doi:10.1007/11546382_2. ISBN 978-3-540-28540-3. Retrieved 10 June 2012.
  7. 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 Paterson, Ross (2002). "Control.Arrow". base-4.5.0.0: Basic libraries. haskell.org. Retrieved 10 June 2012.

External links

The Wikibook Haskell has a page on the topic of: Arrows