
On Sun, Jul 15, 2012 at 06:22:01PM +0100, Ross Paterson wrote:
I propose to refactor the Arrow class, so that GHC's arrow notation can be a bit more general. (The module Control.Arrow itself would remain standard Haskell.)
There was resistance to this on two grounds: - a Profunctor class would be more principled - if we're going to change Arrow, we should make other changes too I think the second set of changes is orthogonal, and should be considered separately. Regarding the first, it's certainly true that the original proposal was unsatisfyingly asymmetrical, but the PreArrow class is what I want to generalize most of arrow notation to, and Profunctor would be too much. So here's a revised proposal, which amounts to splitting the Profunctor class into two independent classes: -- | A binary type constructor that is contravariant in its first argument class PreArrow a where premap :: (b -> b') -> a b' c -> a b c -- | A binary type constructor that is covariant in its second argument class PostArrow a where postmap :: (c -> c') -> a b c -> a b c' and changing the Arrow class from class Category a => Arrow a where arr :: (b -> c) -> a b c first :: a b c -> a (b,d) (c,d) -- various functions made methods to allow efficient specializations to class (Category a, PreArrow a, PostArrow a) => Arrow a where arr :: (b -> c) -> a b c arr f = premap f id first :: a b c -> a (b,d) (c,d) -- rest unchanged with instances instance PreArrow (->) instance PostArrow (->) instance Arrow (->) instance PreArrow (Kleisli m) instance Monad m => PostArrow (Kleisli m) instance Monad m => Arrow (Kleisli m) The default implementation of arr could alternatively be postmap f id, but one has to choose one; perfect symmetry is unattainable. There's also the question of whether it's worth interposing a method-less class class (PreArrow a, PostArrow a) => Profunctor a