[Haskell-cafe] Capitalization and associated type families

Brian Hulley brianh at metamilk.com
Mon Aug 4 18:04:40 EDT 2008

Jonathan Cast wrote:
> On Mon, 2008-08-04 at 19:51 +0100, Brian Hulley wrote:
>> For example, why is there any distinction between a type "variable" and 
>> a type "constant"?
>> 	forall a b. (a -> b) -> List a -> List b
>> Now this begs the question: why does "List" need to start with a 
>> capital? (supposing that quantifiers were always written explicitly)
> AFAIK, it doesn't; the variable/constant distinction is just there to
> let the implementation put the foralls in for you.

Hi Jonathan - thanks - this confirms what I've been thinking. However 

	class Foo a where

		f :: a -> b -> (a, b)

Here there is no capitalization distinction in the type of (f) but the 
implementation can still insert the "forall b." since (a) is already in 
scope. Therefore similarly, if type constructors like "List" were 
instead written using lowercase, since they would already be in scope it 
would be clear even without explicit quantifiers that (a) and (b), but 
not (list), were to be quantified in the type of (map) (assuming of 
course that there was no top level data decl for (a) or (b)).

>  Similarly, if we had
> explicit foralls on equations, we could say
> forall n x xn. drop (n+1) (x:xn) = drop n xn
> but
> forall n. drop n nil = nil
> and it would be perfectly clear that `nil' in the latter case was a
> constructor.

Actually I quite like the above because it shows that pattern matching 
can be understood in terms of universally quantified predicates.

Regarding the verbosity, patterns are something of a special case since 
variables (that are introduced in the pattern) can only occur once and 
there is no need to have higher rank quantification in value patterns 
(disregarding explicit tests for _|_). Therefore special syntax could be 
used to make the above shorter e.g. borrowing the '?' from Felix 
  (section 2.11/2.17 etc)):

	drop (?n + 1) (_ : ?xn) = drop n xn
	drop ?n nil = nil

(where glued prefix binds tighter than application).

> Of course, if you want to introduce this rule, you'd better start out
> with it and be consistent --- require every variable to be explicitly
> brought into scope.  I think you'd find it pretty annoying after trying
> to program in your new language for a while, though.

I agree that there are many good points in favour of Haskell's use of a 
case distinction, not the least being that it gives definite guidance on 
when to use lower or upper case identifiers and therefore avoids the 
mess you find in C++ programs where every programmer has their own 
private conventions which can lead to confusion and useless debate.

However it still seems to me that the case distinction, at least on the 
level of type constructors, becomes problematic and possibly 
inconsistent especially if I consider the effects of trying to 
incorporate something like the ML module system as well as type classes. 
(For example the Moby language (http://moby.cs.uchicago.edu/ ), a 
possible successor to SML, uses capitalization for type constructors 
similar to Haskell which means that type parameters in functor 
applications must be uppercase, which conflicts with the use of 
lowercase type params for classes which are a special kind of functor... 
(Moby itself doesn't encounter any difficulty since it doesn't have type 

Best regards,

More information about the Haskell-Cafe mailing list