<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 11, 2010, at 11:48 AM, Gregory Crosswhite wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; ">No, but there is no point in using a formalism that adds complexity without adding functionality. &nbsp;Arrows are more awkward to use than monads because they were intentionally designed to be less powerful than monads in order to cover situations in which one could not use a monad. &nbsp;When your problem is solved by a monad there is no point in using arrows since an arrow require you to jump through extra hoops to accomplish the same goal.<br><font class="Apple-style-span" color="#006312"><br></font></span></blockquote><div><br></div><div>But they do "add" functionality. &nbsp;An arrow is something like a monad/co-monad pair. &nbsp;Half of the arrow is defined to parse input. &nbsp;The other half is defined to process the parse tree and produce output. &nbsp;An arrow is "just" a functor from one named type to another.</div><br><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; ">No, that is not at all the problem with arrows. &nbsp;The problem with arrows is that they are more restrictive than monads in two respects. &nbsp;First, unlike monads, in general they do not let you perform an arbitrary action in response to an input. &nbsp;Second, they place restrictions on how you define the input arguments of the arrow because you can't feed the output of one arrow into to input of the next unless said input is captured in the arrows type.</span></blockquote></div><br><div>They aren't more restrictive. &nbsp;Just use an identity comonad for the input half if you want to deal with monads. &nbsp;You can even make monad instances for arrows of this form. &nbsp;The latter objection is rather the point of using an arrow. &nbsp;"Parser -&gt; Process", in a single construct. &nbsp;There is an analogy here. &nbsp;A monad, &nbsp;in general corresponds to a catamorphism on a functor algebra. &nbsp;A co-monad corresponds to an anamorphism. &nbsp;The compositon of an anamorphism and catamorphism is a hylomorphism. &nbsp;A thing that unwraps and re-wraps.</div><div><br></div><div>I do tend to use the functor type class (or category-extras, or even data.category) much more than arrows, though. &nbsp;It's all more-or-less the same.</div></body></html>