http://blog.romanandreg.com/post/2755301358/on-how-haskells-...
That's about the limit of my comprehension of arrows. When you see a type (Arrow arr) => arr a b, you should read it as "an arrow from a to b", just like a function (a -> b) can be read "a function from a to b". But an arrow can encompass a monad, a function a -> m b is also an arrow, a Kleisli arrow with type Kleisli m a b. So this means you can use the arrow composition functions with normal functions as well as monadic functions, as well as arrows of other types which need not be functions at all.
Beyond that, all I know is that arrows provide composition functions that allow you to build a digraph of computations where inputs come in, get split off, passed through other arrows and recombined in interesting ways, and there is an arrow syntax which is so convoluted I've never been able to understand the relationship between it and the fundamental arrow combinators. I have never run into a situation where knowing anything about arrows was useful, other than because (&&&) is a neat combinator if you're want tuples. Practice doesn't seem to have caught up to the theory here, and things like applicative functors, which are simpler than monads in some sense, are a lot more useful than arrows, which are more complex. This blog post illustrates a case where arrows were handy, but he winds up using applicative functors in the end also:
http://jaspervdj.be/posts/2012-01-14-monads-arrows-build-sys...
It's a curious thing about functional programming that often what's simpler in theory (monoids, functors) turn out to be more useful in complex situations in the real world than what's more complex in theory.
One last note, I wrote a blog post about this in 2007 with FizzBuzz. Forgive me if it's horrible; I haven't given it much thought since, but here it is:
http://old.storytotell.org/blog/2007/04/08/haskell-arrows.ht...