This is me recording some half-formed thoughts that have been rattling around
in my head for the last week. They concern haskell’s
Arrow
typeclass; in particular it’s frustrating inability to be applied to types that
are in Category
but have no suitable implementation for `arr`

.

Consider something as simple as:

```
newtype Bij a b = Bij (a -> b) (b -> a)
```

a `Category`

instance is trivial, but an `Arrow`

instance is impossible, since
we would need to supply a `b -> a`

given only a `a -> b`

.

And yet most of the `Arrow`

methods (except `arr`

and `&&&`

) would be useful
for, and can be implemented in a very reasonable way, for the type above:

```
(Bij bc cb) *** (Bij xy yx) = Bij (bc *** xy) (cb *** yx)
first b = b *** id
second b = id *** b
```

We omit `&&&`

above because there isn’t a reasonable way to define a general
function `:: (c -> b) -> (c' -> b) -> ((c,c') -> b`

```
(Bij bc cb) &&& (Bij bc' c'b) = Bij (bc &&& bc') undefined
```

…without something like a “restricted Arrow” where `b`

is constrained to
`Monoid`

. (but I’m getting ahead of myself; more on why I don’t think `&&&`

belongs in Arrow anyway below).

Or as a *reductio ad absurdum*, consider simply the following type:

```
newtype Flipped a b = Flipped (b -> a)
```

is there any reason we shouldn’t have an Arrow-like class for which the above can be an instance?

None of this is new; it is a common complaint about Arrow: that it is overly complex (to the point of feeling arbitrary), while being extremely limited.

## Won’t someone think of the Lenses?

Anyone who has tried to write a
lens library has wished they
could use the Arrow abstraction and slammed their head into a wall for at least
an hour before giving up (except probably Edward Kmett). They just really
*ought* to be Arrows.

Consider this lens representation:

```
newtype Lens a b = Lens (a -> (b -> a, b))
```

`&&&`

will give us the same problems as the (admittedly very similar) `Bij`

example above, but the other methods `(***)`

,`first`

and `second`

have good
implementations that would even preserve the Lens Laws (they are what you
would expect, but also have some foundations in CT)

An ArrowChoice implementation should also be no problem to implement while also being practically useful for lenses.

Again though, `arr`

presents a problem. One might even try to implement it as a
getter combined with a const/“read-only” setter continuation like:

```
arr f = Lens $ \a-> (const a, f a)
```

But this violates the first Arrow law `arr id = id`

.

## What is the nature of the problem?

From the above, it is obvious that we have problems with types where the flow
of the computation is reversed from the order of the type variables. We can
also probably find types that are sort of *composite categories* with a
natural Category instance but no way to lift a pure computation.

But here’s another slightly different type of example; a computation with an associated cost, perhaps defining the “energy required” for a certain transformation:

```
data Transformation a b = T Int (a -> b)
instance Category Transformation where
id = T 0 id
(T n f) . (T n' g) = T (n+n') (f . g)
```

Again, this type lends itself well to the parallel composition operators in
Arrow. For instance `&&&`

can capture that composing two transformations into a
single one that “fans out” carries the cost of the sum of their energy
requirements:

```
(T n f) &&& (T n' g) = T (n+n') (f g)
```

But the only logical implementation for `arr`

that we can define,
`arr f = T 0 f`

, breaks the law `arr (f >>> g) = arr f >>> arr g`

.

I started to do a survey of types on hackage that are `Category`

but not
`Arrow`

, but got burnt out at the stage where I had to actually look through
the code. Still this would be a great thing to do.

## Default implementations without `arr`

If we rip `arr`

out of the Arrow class, we lose a lot of the default methods,
which are implemented in terms of some primitive “identity-like” functions
lifted to `Arrow`

with `arr`

. Here are those functions from the main class:

```
-- second in terms of first, and vice versa:
\(x,y) -> (y,x)
-- &&& in terms of ***:
\b -> (b,b)
```

and these are the helpers from `ArrowChoice`

:

```
-- right in terms of left:
either Right Left
-- ||| in terms of +++:
either id id
```

It’s useful to try to think of implementing these primitive helpers in a given
Category, e.g. for some `Category c`

can we implement `swap :: c (x,y) (y,x)`

?
And for any Category where we can define `swap`

does it follow that we should
always be able to define the corresponding `ArrowChoice`

helper
`swapE :: c (Either a b) (Either b a)`

? If so, then they should be in the same
new sub-class of Category, etc., etc.

I think these primitive helpers would probably be a good basis for the methods in a new class or set of classes to act as an Arrow alternative.

## what about all those laws?

Most of the invariants that should hold for an Arrow are defined in terms of
`arr`

, but I think there are probably reasonable replacements, especially since
there was never anything particularly rigorous about the original Arrow laws.

For example, here are some relationships which I think should be expected to hold:

`first id = second id = id`

`f *** g = first f >>> second g`

(straight from default implementation)

but I’m not very good at this.

I suspect `arr`

is either the anchor that allows for a well-defined Arrow
class, or that all the laws are necessary to deal with the inclusion of `arr`

.
I hope the latter, and that a revised set of laws for Arrow-without-arr would
look simpler and more abstract, like
Monoid.

## About `&&&`

While an arrow that can “fan out” is useful, this doesn’t belong in this class for a number of reasons:

It doesn’t depend on

`Category`

at all and doesn’t even require a type of kind`* -> * -> *`

; since any Arrow can be made an Applicative anyway, this could be re-written as`(&&&) :: Applicative a=> a c -> a c' -> a (c,c')`

it appears only

*once*in the entire implementation (in the`Arrow`

class declaration). The Arrow laws don’t require it, nor do any of the default class implementations use it.because there are many Arrow-like things which have no suitable implementation for such a function (a bit of circular logic, I know)

## Concluding remarks

Arrow fails as a generally-useful and coherent class for composing Categories vertically or “in parallel”, which is I think what people are looking for.

Maybe I can come up with some code soon for a better Arrow. Such a set of classes would hopefully be simpler, more flexible, and take advantage of the Arrow = Category + Applicative correspondence.

Also as I was finishing this I just stumbled on Causal Commutative Arrows (PDF) which look interesting.

Let me know your thoughts.

### Update 2/13

Thanks for all the feedback everyone. From the comments I was pointed to Adam Megacz’s work on “generalized arrows”, and there are also a few comments on the haskell subreddit.