
On Thu, 20 Sep 2007, Jon Fairbairn wrote:
Henning Thielemann
writes: On Mon, 17 Sep 2007, Jon Fairbairn wrote:
instance Arrow (->) where ... (***) = (Data.Tuple.***) (&&&) = (Data.Tuple.&&&)
and modules that imported only Arrow (not Tuple) would see no difference from the present state of affairs. Where things would be different would be if a module imported both Tuple and Arrow, when, instead of a name clash, *** and &&& would get their Arrow meanings (albeit with a specialised instance for ->).
If you import Tuple and Arrow, why not just import Arrow?
Presumably because there are functions in Tuple that aren't in Arrow (if that isn't the case, this just means that Tuple/Arrow isn't a very good example).
I would certainly import Arrow unqualified, and Tuple qualified. Or I would import the infix operators of Tuple, that do not interfer with Arrow, explicitly but unqualified. I think many problems arise from a dislike against both qualified and explicit imports. In the Modula languages only the latter two options exists and it works. Actually, one of my points is that specialised functions even shall have special names in order to signal to the reader which concrete data type is processed. I think most people agree, that infix operators shall be used unqualified. Since unqualified usage means automatic resolution of the particular implementation, they are predestinated for class methods. That is, (+) is polymorphic and this is fine, and (++) should also be polymorphic, maybe replacing 'mplus'. The specialised functions should have alphanumeric identifiers, say List.append, Int.add. Whenever I read in a program List.map (Int.add 1) (List.append a b) I'm confident, that a and b are lists, not just any possible monads, and that the lists contain Ints.