proposal #2517: remove 'pure' method from Arrow class

Isaac Dupree isaacdupree at charter.net
Fri Aug 15 09:58:10 EDT 2008


Ross Paterson wrote:
> The Arrow class as originally defined by John Hughes had methods arr, >>>
> and first.  (>>> has since been moved by #1773 to the Category class.)
> When writing the "Fun of Programming" paper, I added pure as a synonym
> for arr, because Richard Bird preferred it.  However this name hasn't
> caught on, and now it clashes with a method in the Applicative class,
> so I propose to remove it.

I agree with deleting 'pure' from there. Now assuming that, 
I'm wondering...

It looks like all Arrows are Applicative; is that a useful 
observation? (and then even further off topic, but it's 
still important); As follows:

<*> :: (Applicative f) => f (a -> b) -> f a -> f b
so
<*> :: (Arrow arr) => arr x (a -> b) -> arr x a -> arr x b
fmap :: (Arrow arr) => (a -> b) -> arr x a -> arr x b
pure :: (Applicative f) => a -> f a
pure :: (Arrow arr) => a -> arr x a

Interesting, it looks a bit similar to 'Reader x', is that okay?

instance (Arrow arr) => Applicative (arr x) where
   pure a = arr (const a)
   fmap f a = a >>> arr f
   f <*> a = fmap (uncurry ($)) (f &&& a)

But I seem to recall arrConst indeed being of significance, 
for example.  And the above definition of <*> preserves the 
ordering of f and a; for example, the effect-order-reversing 
Applicative-transformer could accurately be applied here. 
So I think it's nontrivially useful.  Not all Applicatives 
are Arrows though!

ArrowPlus, of course, corresponds with Alternative; the full 
types of the appending operation's arguments must be 
identical in all cases.
instance (Arrow arr) => Alternative (arr x) where
   empty = zeroArrow; (<|>) = (<+>)
and thenceforth with Monoid
instance (Arrow arr) => Alternative (arr a b) where
   mempty = zeroArrow; mappend = (<+>)
. It makes me wonder what is the point of ArrowPlus, 
MonadPlus, Alternative... when we have Monoid.

But are they usable in all the same situations?  It seems 
some places that use
f :: (MonadPlus f) => ...
would indeed need to require the polymorphic (invented syntax)
f :: (forall a. Monoid (f a)) => ...
not just for some particular 'a'
f :: (Monoid (f a)) => ...

Why does that make sense? Should it?  Did I get confused 
somehow?

-Isaac


More information about the Libraries mailing list