[Haskell-cafe] Capitalization and associated type families

Brian Hulley brianh at metamilk.com
Mon Aug 4 14:51:27 EDT 2008


Hi,
I'm familiar with the capitalization rules for identifiers in Haskell 
and know that they are very useful and practical e.g. by allowing 
variables to be distinguished from "constants" in patterns etc.

However I'm trying to understand on a much deeper level whether or not 
they can really be justified and indeed if there is a danger that they 
can lead to inconsistency in the light of future extensions to the language.

For example, why is there any distinction between a type "variable" and 
a type "constant"?

To make this clearer consider the type of (map):

	(a -> b) -> List a -> List b

(ignoring the special [] syntax for list types which would just confuse 
the issue here).

With explicit quantifiers, we'd write:

	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)

The same distinction between "constants" and "variables" is also used in 
predicate logic e.g.

	On(x, Table) & Colour(x, Red)

but similarly the above could surely be written just as easily by:

	exists x. on(x, table) & colour(x, red)

where (on), (table), (colour), and (red) are just considered to be 
variables that have already been introduced (by some enclosing scope) 
instead of having to think of them as "constants" and make a distinction 
between "constant" and "variable".

Anyway to get to the point of this post what I'm really trying to find 
is some explanation of why there is the concept of "constant" as opposed 
to "variable" or whether this concept is now redundant in the light of 
lexical scoping/ explicit quantification?

Somewhat related to this issue is the syntax of associated type 
families. For example in section 5.2.2 of 
http://www.haskell.org/haskellwiki/GHC/Indexed_types there is the example:

	class C a b where
		data T a

which raises in my mind several questions:

1) Why is (T) given a parameter? I.e. why does an associated type 
declared inside a class decl not automatically get all the parameters of 
the class passed to it so that one would just write:

	class C a b where
		data T
		f :: T -> T
===
	data family T a b
	class C a b where ...
		f :: T a b -> T a b

2) Compare:

	class C a b t | a b -> t
with
	class C a b where
		data T

In other words, why is (T) a "constant" when it is declared inside the 
class but a "variable" when passed as a parameter?

Is the fact that (T) needs to be given a parameter even when it is 
declared inside the "scope" of the class type parameters the result of 
needing to fulfill the idea of "constant" vs "variable"?

3) In the syntax:

	class C a b
		data T a

it seems rather odd that the "a" in "T a" should be related to the "a" 
in "C a b" since one might expect that the name chosen for a parameter 
should be local to the data decl.

Apologies for such a rambling post. I've spent literally at least 6 
months scouring the internet trying to find a real discussion about 
capitalization rules because I'm trying to answer the following 
question: if I make use of a similar capitalization rule in my own 
language, can I guarantee that this rule will not lead to an 
inconsistency at some future point? Ie is there a real rock solid 
theoretical basis for making a distinction between "constants" and 
"variables" that holds even in the presence of lexical scoping?

Thanks, Brian.


More information about the Haskell-Cafe mailing list