After having played with some packages that use arrows, and after having read the very nice "programming with arrows" paper I wanted to build some of my own.

Strangely my code did not work, even the simplest function got stuck in an infinite loop or gave a stack overflow.

I quickly noticed I made a really stupid mistake, I forget to implement "arr"! However, the compiler did not give a warning on this. So I wandered how it was possible that the Arrow package had a default implementation for something so specific as arr?

The code revealed the following:

	-- | Lift a function to an arrow: you must define either this
	--   or 'pure'.
	arr :: (b -> c) -> a b c
	arr = pure

	-- | A synonym for 'arr': you must define one or other of them.
	pure :: (b -> c) -> a b c
	pure = arr
Ah, so the default implementation of arr is pure... and vice versa...

This feels like rather incorrect to me, but my feelings are based on imperative background knowledge, so this might be totally correct design in Haskell.

Why not force people to implement arr and leave just pure as the synonym? And if pure is really a synonym for arr, what does it do inside the Arrow type class? Does it ever make sense to have a different implementation for arr and pure?


Thanks for any help,
Peter