arrows

Wolfgang Jeltsch wolfgang@jeltsch.net
03 Jun 2002 18:22:41 +0200


On Saturday, 2002-05-25, 13:25, CEST John Hughes wrote:
> On Sat, 25 May 2002, Koen Claessen wrote:
> 
> >
> > There are many types which would fit nicely in an arrow
> > framework, but do not because of the demand of these
> > operators, here are two examples:
> >
> >   * Isomorphisms, are nice arrows:
> >
> >       type Iso a b = (a -> b, b -> a)
> >
> >     but of course not all functions have an appropriate
> >     inverse, so arr cannot be defined.
> >
> >   * Stream processors (from Fudgets) are nice arrows:
> >
> >       data SP a b = Get (a -> SP a b) | Put a (SP a b) | Nil
> >
> >     But the first operator assumes that the product type
> >     associated with this arrow must be Haskell's product
> >     (,), but in fact a sum type would make a much nicer
> >     product.
> >
> > The reason why John chose to lay out the arrow library as it
> > is (I think) is because of:
> >
> >   * Simplicity; if you are too general then you get lots of
> >     painful classes all over the place.
> >
> >   * Sufficiency; all examples he considered in his paper fit
> >     into the current framework.
> >
> > It is not clear if the design of the arrow library should be
> > redone just because some particular examples do not fit in.
> > After all, there are many examples of monads (Sets for
> > example) which can not be made instance of the current monad
> > class in Haskell.
> >
> > Regards,
> > /Koen.
> 
> Exactly. The other reason is that I was dubious that one can do very much
> WITH an arrow that doesn't have first. It's all very well to be able to
> make various types into instances, but if the combinators aren't then
> useful, then you've suffered extra complexity in the class structure for
> nothing.
> 
> This is a compromise, of course, and I could be persuaded that it would be
> better to split the Arrow class -- but only if the new instances can then
> be USED in a useful way.
> 
> John

Hello,
one could, for instance, define an arrow-based mapping function without
using first:
    amap :: Arrow a => (c -> d) -> a b c -> a b d 
    amap f a = a >>> arr f 
I could imagine that there are at least as many uses for Arrow without
first as they are for Functor.
In addition, if (by excluding first) more types would be instances of
Arrow, more composition and pure operations could be expressed by the
"standard" functions from the Arrow class instead of individual
functions for every type. Connections between operations for different
types would be expressed adequately and one would gain additional
clarity and consistency.
And as I wrote already, a reason for having an Arrow class without first
and a subclass which introduces first is that first would be handled the
same way left is handled. This would, in my opinion, result in a more
consistent class system.

Wolfgang