How can I implement this arrow? Thanks

Ashley Yakeley ashley at semantic.org
Tue Sep 16 02:52:03 EDT 2003


In article <Sea1-F33yfxRydC3hSs00038d72 at hotmail.com>,
 "Yu Di" <diyu01 at hotmail.com> wrote:

> Hi, I want to create an arrow which is essentially
> 
> data MyArrow a b = MyArrow ((String, a) -> (String,b))

I don't think this type is an arrow. For a "product arrow", i.e. an 
instance of Hughes' "Arrow" class with "first" defined, you can define 
this:

  arrProduct :: arrow p q -> arrow p r -> arrow p (q,r);
  arrProduct apq apr =
    arr (\p -> (p,p)) >>>
    first apr >>>
    arr (\(r,p) -> (p,r)) >>>
    first apq;

This has a certain intuitive symmetry in its arguments, though for 
instance for a Kleisli arrow (a -> m b for some monad m), arrProduct 
will essentially execute one before the other. But if you try to define 
this directly for MyArrow, you'll find you need to pick one of the two 
Strings (losing information) or else combine them somehow. Perhaps this:

  arrProduct (MyArrow f1) (MyArrow f2) = MyArrow (\sa -> let
    {
    (s1,b1) <- f1 sa;
    (s2,b2) <- f2 sa;
    } in (s1 ++ s2,(b1,b2)));

In general, a type of the form (f a -> f b) is an arrow if f is a 
Functor that has one of these:

  fApply :: f (a -> b) -> f a -> f b;
  fProduct :: f a -> f b -> f (a,b);

I call this class of Functors "FunctorApply", but maybe someone has a 
better name. I'm not sure what the attached laws are, but I imagine 
they're fairly straightforward.

-- 
Ashley Yakeley, Seattle WA



More information about the Haskell mailing list