
it's because you not programmed a lot with type classes. if you start, you will soon realize that type signatures with classes are just unreadable. just look at sources of my streams library
copyStream :: (BlockStream h1, BlockStream h2, Integral size) => h1 -> h2 -> size -> IO ()
I know this is probably just a personal preference, but I have to say that this syntax (the canonical Haskell'98 one) is by far the most readable and instantly clear of any of the alternatives that have been suggested in this thread: copyStream :: BlockStream* -> BlockStream** -> Integral -> IO () Here you have invented a new notation for type variables (* and **), when we already have a perfectly good one. copyToMemoryStream :: BlockStream -> MemoryStream -> Integral -> IO () Whereas here, the lack of any type variable means I am no longer aware that overloading is going on. This is likely to discourage the reuse of this code fragment, rather than encourage it. copyStream :: {BlockStream} h1 -> {BlockStream} h2 -> {Integral} size -> IO () What is gained by attaching the constraints inline with the type variables? If the type variable occurs more than once, which occurrence should I attach the constraint to? What if I attach different constraints to different occurrences of the same variable? (Obviously the union is intended, but writing constraints in several different locations would be highly confusing). But at least there is a syntactic marker ({}) that overloading is happening. copyStream :: {BlockStream} -> {BlockStream} -> {Integral} -> IO () Again, omitting type variables means that the possible mental confusion over whether the two {BlockStream} constraints apply to the same implicit variable or to different ones is unpleasant. Better to be fully explicit, after all, it only takes one extra character to name the variable!
foo :: Collection c a => a -> c === foo :: {Collection c} a -> c
foo :: Collection c a => c -> c === foo :: {Collection * a} c -> c
forall a. Num a => (forall b. (Coll b a, Ord b) => b a -> ()) -> () === (forall b. {Coll * a, Ord}b {Num}a -> ()) -> () === forall a. (forall b. ({Coll * a, Ord} b) ({Num} a) -> ()) -> ()
The lengths people will go to in making things difficult for the reader, just to save a few characters is truly amazing. Remember, the code will be read many more times than it is written. IMHO, the various proposed sugar adds nothing helpful, and just muddies understanding. Regards, Malcolm