|
|
Line 1: |
Line 1: |
| In [[computer science]], '''arrows''' are a [[type class]] used in [[programming language|programming]] to describe [[computation]]s in a [[pure function|pure]] and [[declarative programming|declarative]] fashion. First proposed by computer scientist [[John Hughes (computer scientist)|John Hughes]] as a generalization of [[monad (functional programming)|monad]]s, arrows provide a [[referential transparency (computer science)|referentially transparent]] way of expressing relationships between ''logical'' steps in a computation.<ref name=Hughes98>{{cite journal
| | I am Oscar and I totally dig that name. Her family lives in Minnesota. Doing ceramics is what adore performing. I utilized to be unemployed but now I am a librarian and the wage has been truly fulfilling.<br><br>Here is my weblog ... [http://www.onbizin.co.kr/xe/?document_srl=354357 std testing at home] |
| |last=Hughes |first=John |date=May 2000 |title=Generalising Monads to Arrows |journal=Science of Computer Programming |volume=37 |issue=1-3 |pages=67–111 |publisher=Elsevier |doi=10.1016/S0167-6423(99)00023-4 |issn=0167-6423 |url=http://pdn.sciencedirect.com/science?_ob=MiamiImageURL&_cid=271600&_user=10&_pii=S0167642399000234&_check=y&_origin=search&_zone=rslt_list_item&_coverDate=2000-05-31&wchp=dGLzVlk-zSkWb&md5=fa91ab4ffc136b0cedc52318c7c249be&pid=1-s2.0-S0167642399000234-main.pdf |format=PDF |accessdate=10 June 2012
| |
| }}</ref> 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 [[parser]]s among other applications.<ref name=Hughes98 /><ref name=Paterson03>{{cite book
| |
| |last=Paterson |first=Ross |editor1-last=Gibbons |editor1-first=Jeremy |editor2-last=de Moor |editor2-first=Oege |title=The Fun of Programming |publisher=Palgrave Macmillan |date=27 March 2003 |pages=201–222 |chapter=Chapter 10: Arrows and Computation |isbn=978-1403907721 |url=http://www.soi.city.ac.uk/~ross/papers/fop.ps.gz |format=PS.GZ |accessdate=10 June 2012
| |
| }}</ref>
| |
| | |
| == 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 [[library (computing)|libraries]], such as the [[Fudgets]] library for [[graphical user interface]]s and certain efficient parsers, defied rewriting in a monadic form.<ref name=Hughes98 />
| |
| | |
| 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.<ref name=Hughes98 /> 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.<ref name=Lindley10>{{cite journal
| |
| |last1=Lindley |first1=Sam |last2=Wadler |first2=Philip |last3=Yallop |first3=Jeremy |date=January 2010 |title=The Arrow Calculus |journal=Journal of Functional Programming |volume=20 |issue=1 |pages=51–69 |publisher= |doi=10.1017/S095679680999027X |issn=0956-7968 |url=http://homepages.inf.ed.ac.uk/wadler/papers/arrows-jfp/arrows-jfp.pdf |format=PDF |accessdate=10 June 2012
| |
| }}</ref>
| |
| | |
| In [[category theory]], the [[Kleisli categories]] of all [[monad (category theory)|monad]]s form a proper subset of Hughes arrows.<ref name=Hughes98 /> While [[Freyd category|Freyd categories]] were believed to be [[equivalence of categories|equivalent]] to arrows for a time, it has since been proven that arrows are even more general. In fact, arrows are not merely equivalent, but directly equal to [[enriched category|enrich]]ed Freyd categories.<ref name=Atkey11>{{cite journal
| |
| |last=Atkey |first=Robert |date=8 March 2011 |month= |title=What is a Categorical Model of Arrows? |journal=Electronic Notes in Theoretical Computer Science |volume=229 |issue=5 |pages=19–37 |publisher=Elsevier |doi=10.1016/j.entcs.2011.02.014 |issn=1571-0661 |url=http://pdn.sciencedirect.com/science?_ob=MiamiImageURL&_cid=272990&_user=10&_pii=S157106611100051X&_check=y&_origin=article&_zone=toolbar&_coverDate=08-Mar-2011&view=c&originContentFamily=serial&wchp=dGLzVBA-zSkzS&md5=d479e9216510ae882e9db588ac09dad5&pid=1-s2.0-S157106611100051X-main.pdf |format=PDF |accessdate=10 June 2012
| |
| }}</ref>
| |
| | |
| == 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 [[function (mathematics)|function]]s (represented in Haskell by an arrow symbol) to combine in a [[reification (computer science)|reified]] form. However, the actual term "arrow" may also come from the fact that some (but not all) arrows correspond to the [[morphism]]s (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.<ref name=Hughes05>{{cite conference
| |
| |last=Hughes |first=John |title=Programming with Arrows |year=2005 |conference=5th International Summer School on Advanced Functional Programming. 14–21 August 2004. Tartu, Estonia |editor1-last=Uustalu |editor1-first=Tarmo |editor2-last=Vene |editor2-first=Varmo |booktitle=Advanced Functional Programming |pages=73-129 |doi=10.1007/11546382_2 |isbn=978-3-540-28540-3 |publisher=Springer |url=http://www.cse.chalmers.se/~rjmh/afp-arrows.pdf |format=PDF |accessdate=10 June 2012
| |
| }}</ref>
| |
| | |
| === Functions ===
| |
| The description currently used by the Haskell [[standard libraries]] ''requires'' only two basic operations:
| |
| * A [[type constructor]] <math>arr</math> that takes functions <math>\to</math> from any type <math>s</math> to another <math>t</math>, and lifts those functions into an arrow <math>A</math> between the two types.<ref name=HaskArrows>{{cite web
| |
| |last=Paterson |first=Ross |title=Control.Arrow |year=2002 |work=base-4.5.0.0: Basic libraries |publisher=haskell.org |url=http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html |accessdate=10 June 2012
| |
| }}</ref>
| |
| <source lang="haskell">
| |
| arr (s -> t) -> A s t
| |
| </source>
| |
| * A piping method <math>first</math> that takes an arrow between two types and converts it into an arrow between [[tuple]]s. The first elements in the tuples represent the portion of the input and output that is altered, while the second elements are a third type <math>u</math> describing an unaltered portion that bypasses the computation.<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| first (A s t) -> A (s,u) (t,u)
| |
| </source>
| |
| | |
| 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 [[category (mathematics)|categories]], they can [[inheritance (computer science)|inherit]] a third operation from the class of categories:
| |
| * A [[function composition|composition]] operator <math>\ggg</math> that can attach a second arrow to a first as long as the first function's output and the second's input have matching types.<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| A s t >>> A t u -> A s u
| |
| </source>
| |
| | |
| One more helpful method can be derived from a combination of the previous three:
| |
| * A merging operator <math>***</math> that can take two arrows, possibly with different input and output types, and fuse them into one arrow between two compound types. Note that the merge operator is ''not'' necessarily [[commutative]].<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| A s t *** A u v -> A (s,u) (t,v)
| |
| </source>
| |
| | |
| === Arrow Laws ===
| |
| In addition to having some well-defined procedures, arrows must obey certain rules for any types they may be applied to:
| |
| * Arrows must always preserve all types' [[identity morphism|identities]] <math>id</math> (essentially the definitions of all values for all types within a category).<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| arr id == id
| |
| </source>
| |
| * When connecting two functions <math>f</math> & <math>g</math>, the required arrow operations must [[distributivity|distribute]] over compositions from the left.<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| arr (f >>> g) == arr f >>> arr g
| |
| first (f >>> g) == first f >>> first g
| |
| </source>
| |
| * In the previous laws, piping can be applied directly to functions because order must be irrelevant when piping & lifting occur together.<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| arr (first f) == first (arr f)
| |
| </source>
| |
| | |
| The remaining laws restrict how the piping method behaves when the order of a composition is reversed, also allowing for simplifying [[expression (computer science)|expression]]s:
| |
| * If an identity is merged with a second function to form an arrow, attaching it to a piped function must be commutative.<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| arr (id *** g) >>> first f == first f >>> arr (id *** g)
| |
| </source>
| |
| * Piping a function before type simplification must be equivalent to simplifying type before connecting to the unpiped function.<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| first f >>> arr ((s,t) -> s) == arr ((s,t) -> s) >>> f
| |
| </source>
| |
| * Finally, piping a function twice before [[associativity|reassociating]] the resulting tuple, which is nested, should be the same as reassociating the nested tuple before attaching a single bypass of the function. In other words, stacked bypasses can be flattened by first bundling together those elements unchanged by the function.<ref name=HaskArrows />
| |
| <source lang="haskell">
| |
| first (first f) >>> arr ( ((s,t),u) -> (s,(t,u)) ) ==
| |
| arr ( ((s,t),u) -> (s,(t,u)) ) >>> first f
| |
| </source>
| |
| | |
| == 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 (programming)|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.<ref name=Hughes05 />
| |
| | |
| == Utility ==
| |
| Arrows have several benefits, mostly stemming from their ability to make program logic explicit yet concise. Besides avoiding [[side effect (computer science)|side effects]], [[purely functional]] programming creates more opportunities for [[static code analysis]]. This in turn can theoretically lead to better [[compiler optimization]]s, easier [[debugging]], and features like [[syntax sugar]].<ref name=Hughes05 />
| |
| | |
| Although no program strictly requires arrows, they generalize away much of the dense [[first-class function|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 [[interface (computing)|interface]]s simple.<ref name=Hughes05 />
| |
| | |
| 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.<ref name=Hughes05 /> Another issue, which applies to many [[functional programming]] constructs, is efficiently [[compiling]] code with arrows into the [[imperative programming|imperative]] style used by computer [[instruction set]]s.{{Citation needed|reason=This statement is commonly heard, but no strong, specific source on hand|date=June 2012}}
| |
| | |
| == References ==
| |
| {{Reflist}}
| |
| | |
| == External links ==
| |
| {{Wikibooks|Haskell|Arrows}}
| |
| * [http://www.haskell.org/arrows Arrows: A General Interface to Computation]
| |
| * [http://www.soi.city.ac.uk/~ross/papers/notation.html A New Notation for Arrows], Ross Paterson, in ICFP, Sep 2001.
| |
| * [http://www.haskell.org/ghc/docs/latest/html/users_guide/arrow-notation.html Arrow notation] ghc manual
| |
| | |
| [[Category:Functional programming]]
| |
I am Oscar and I totally dig that name. Her family lives in Minnesota. Doing ceramics is what adore performing. I utilized to be unemployed but now I am a librarian and the wage has been truly fulfilling.
Here is my weblog ... std testing at home