
Sorry for my slow reply,
Well, it doesn't seem like we're anywhere near a consensus so I'll
just drop this proposal.
Let me just finish off by clarifying my views on this ticket as I
answer Henrik's post.
On 10/19/07, Henrik Nilsson
So, with the risk of stating what has already been covered, my concerns are that like Jon I find the reuse of names unfortunate, especially if it is done in what appears to be a very central module. Moreover, as functions are perfectly legitimate arrow instances, I don't really see the point of it all, and I remain unconvinced by the argument that importing Control.Arrow somehow is complicated and scary.
I don't think that importing Control.Arrow is complicated of scary. I just think it gives the wrong mental model of what it going on. In Control.Arrow it's all about the process of transforming one thing into the other. Arrows abstract over transformations and gives support for different varieties including transformations which are stateful, can throw exceptions and so on and so forth. However, when we look at the particular case of the function arrow instance there is a different mental model at play. At least for me. When I see the (&&&) operator instantiated for the function arrow I don't think about the process anymore, I think about the objects being manipulated. And the objects in this case are pairs. The reason is that the function arrow is so common in Haskell that at least I don't think about it as anything special. My focus shift towards the things that form the input and output. And those things are pairs in this case. So this really comes down to thinking about morphisms or thinking about objects if you phrase it in category theory lingo. In my brain these two ways of thinking are different and therefore I like to have separate functions for these two models. Even if it means that two functions are computationally equal. But maybe the problem is simply that I'm stupid and should learn to think about these two mental models as one :-). The other side of the coin is what to name the functions. For this proposal I chose the same names as their generalized counterparts. I can see why that worries people although I don't share that feeling. We have a module system whose purpose is (among other things) to handle names. It does so rather well, consider for instance Data.Map and Data.Set which I use extensively in my everyday programming. They have a lot of function names in common and which also clashes with Prelude names and other libraries. It's not a problem to have several functions having the same name. It's actually a feature which lessens the burden of remembering a ton of names and which shows that their intended semantics is, if not equal, then strongly related. Having these tuple function from my proposal but under different names would be OK for me though. It would be better that not having them at all.
It may well be, of course, that the current class hierarchy isn't factored the right way, i.e. that operations like &&& and *** should live some place else entirely. (This wouldn't be the first instance of such problems.)
That might be true. I don't have any opinion on that.
That's a somewhat orthogonal discussion, though. But defining &&& and *** in more places certainly isn't going to help.
Well, I disagree with that but I've already said why so no need to rehash it here. I guess we can agree to disagree. Cheers, /Josef