Who is afraid of arrows, was Re: [Haskell-cafe] ANNOUNCE: Haskell XML Toolbox Version 9.0.0

Uwe Schmidt uwe at fh-wedel.de
Tue Oct 12 08:56:37 EDT 2010


Hi Gregory,

> ...
> No, but there is no point in using a formalism that adds complexity
> without adding functionality.  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.
> 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.

As I understood, John Hughes invented the arrows as a generalisation
of monads, you say it's a less powerful concept. I'm a bit puzzled with
that. Could you explain these different views.

> ...
> Yes, but the >=> operator lets you do the same thing with monads, and in
> fact I use it all the time to do point-free programming with monads, so
> this isn't at all an advantage that arrows have over monads.

yes, I agree. What about the other combinators (&&&, ***,...)?

> ...
> No, that is not at all the problem with arrows.  The problem with arrows
> is that they are more restrictive than monads in two respects.  First,
> unlike monads, in general they do not let you perform an arbitrary
> action in response to an input. ...

It's rather easy to define some choice combinators. Or am I
missing the point?

> ...  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.
>
> To be more concrete about my second point, suppose you have some monadic
> action
>
>      f :: a -> b -> m c
>
> How would you structure this same action as an arrow?  One thing that
> you could do is take one of the arguments and turn it into the input of
> the arrow:
>
>       f' :: a -> Arrow b c
>
> But now you can't feed the output of an arrow into the first argument.

yes, this a common pattern, a function f' with an extra argument of type a,
and sometimes you want to call f' with some value, e.g. f' 42,
sometimes the extra argument must be computed from the arrow input, let's say 
with an arrow g.

For this case in hxt there is a combinator ($<) with signature

($<) :: (c -> a b d) -> a b c -> a b d

With that combinator you can write

f' $< g

The combinator does the following: The input of the whole arrow
is fed into g, g computes some result and this result together with the
input is used for evaluating f'.  The ($<) is something similar to ($).

> Alternatively, you could pack both arguments into the input of the arrow:
>
>      f'' :: Arrow (a,b) c
>
> Great, but now you have made it more awkward to use f'' because you have
>...

yes, that become rather clumsy.

> ...
> In conclusion, while I greatly appreciate you taking the time to explain
> your reasoning, it still looks to me like there is nothing you have
> gained by using arrows except adding extra unnecessary complexity in
> your library.

So, your advice is to throw away the whole arrow stuff in hxt-10 and
redefined (or rename) the combinators on the basis of monads?

Cheers,

  Uwe



More information about the Haskell-Cafe mailing list