
Tom Ellis
Are there any best-practices I should be aware of with Arrows? Or is it just a case of getting on with it?
The best practice is probably to avoid them. If your type is a monad, there is little reason to use the awkward arrow interface. In some cases the arrow interface can improve the asymptotic performance though, for example in the case of `Auto` (which is actually a monad, but the monadic interface introduces a space leak). In most cases when you expose an `Arrow` interface you can also expose a `Category`+`Applicative` interface, which is pretty much equivalent (except for a few extra laws): proc x -> do y1 <- a1 -< x y2 <- a2 -< x id -< x + y1 + y2^2 Is equivalent to: liftA3 (\x y1 y2 -> x + y1 + y2^2) id a1 a2 All arrows give rise to a [Profunctor] instance, so instead of `arr` you can use `lmap` and `rmap`/`fmap`: arr f . c = fmap f c c . arr f = lmap f c If the interface is not under your control, make yourself comfortable with the complete arrow syntax, most notably how it handles operators, combinators and the `(| banana bracket notation |)`. This is very valuable information. Try to separate individual computations as much as possible and compose using `(.)` (or `(<<<)`/`(>>>)` if you prefer). This makes your code much more readable: c = a . b . c where a = {- ... -} b = {- ... -} c = {- ... -} There is one case where the arrow notation is really indispensable: value recursion via `ArrowLoop`: proc _ -> do rec v <- integral -< x + 1 x <- integral -< v id -< (x, v) Here the position x is the integral of the velocity, which is itself the integral of the position + 1. This is awkward to express in terms of `loop`, so arrow notation is really a big helper here. [Profunctor]: http://hackage.haskell.org/package/profunctors Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.