
Hi Ertugul. Thanks for taking the time to write me an in-depth reply! I have a few comments and a question. On Sat, Jun 22, 2013 at 03:36:15PM +0200, Ertugrul Söylemez wrote:
Tom Ellis
wrote: 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.
Unfortunately my type doesn't have a Monad instance.
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
Yes, I can see how that would be useful. My question is: are you talking about this Applicative instance: data MyArr a b = ... instance Arrow MyArr where ... instance Functor (MyArr a) where fmap f = (arr f <<<) instance Applicative (MyArr a) where pure = arr . const f <*> g = arr (uncurry ($)) <<< (f &&& g)
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.
Interesting. I hadn't noticed the `(| banana bracket notation |)` on the GHC Arrows page[1] before, but just saw it when I went back to check.
Try to separate individual computations as much as possible and compose using `(.)` (or `(<<<)`/`(>>>)` if you prefer). This makes your code much more readable:
Yes, agreed. I'm a strong proponent of using (.) for functions and (<=<) when dealing with Monads.
There is one case where the arrow notation is really indispensable: value recursion via `ArrowLoop`: [...]
I think I will be able to make my Arrow an ArrowLoop, but I haven't checked. Thanks again, Tom [1] http://www.haskell.org/ghc/docs/latest/html/users_guide/arrow-notation.html