Jan Brosius writes:

> Is there anyone who can explain to me what is meant by second rank
> polymorphism.

The system of second-order lambda calculus, or System F, is the system 
you are looking for.  It features rank-2 polymorphism in the sense that 
a polymorphic function may be used at a polymorphic type.

In other words, consider the identity function `id' (using a 
not-quite-Haskell notation):

id :: forall (a :: T) . a -> a
id = /\ a :: T . \ x :: a . x

Here you can see that the function `id' has a polymorphic type: for any 
type `a', it has the type `a->a'.  The definition reflects this: the 
`/\ a' is a type lambda -- the first argument of `id' is a type.  Given 
a type a, it then takes a term x of type a, and returns it.  Thus a 
valid application of id is as follows:

id Int 5   ==>   5

because

(/\a::T.\x::a.x) Int 5  -->  (\x::Int.x) 5  -->  5

Now in ordinary Haskell (or ML), you don't see the type lambdas /\, or 
the foralls.  These are inferred automatically for you.  However, they 
are inferred in such a way that they all appear at the very beginning 
of the types and terms respectively.  There are good technical reasons 
for this.  One consequence is that a function like `id' will never need 
to be applied at a polymorphic type; that is,

id (forall (a::T).a->a) id  ==/==>  id

but is in fact untypeable.  This is OK because you must have been going 
to use the result, and so in reality you have something like

id (Int->Int) (id Int) 5  ==>  5

as expected.

So a rank-1 polymorphic type system, or predicative polymorphism, 
restricts `T' above to only monomorphic (non-polymorphic) types.

Rank-2 polymorphism relaxes this restriction.  Now T is closed under 
forall as well as under (->) and so on, and so polymorphic types may 
appear as arguments.  This also means, necessarily, that foralls may 
appear anywhere in types, not just at the beginning.  For example, in 
System F,

id (forall (a::T).a->a)

has type

(forall (a::T).a->a) -> (forall (b::T).b->b)

Normally the `::T' is dropped, and `forall a::T' is simply written 
`forall a'.  Sometimes `*', aka `the kind of all types', is used: 
`forall a::*'.

In the literature, an actual `forall' symbol, an upside-down A like 
`\/', is usually used instead of `forall'.

References:

There's a discussion in Chapter 9 of:
@Book{
   Mitchell96:Foundations,
   author="John C. Mitchell",
   title="Foundations for Programming Languages",
   publisher="{MIT} {P}ress",
   year="1996",
}
And also in any introduction to type systems or the typed lambda 
calculus, such as the lecture notes originally by Andy Pitts at

http://www.cl.cam.ac.uk/Teaching/1998/Types/

The second-order lambda calculus was independently invented by 
Jean-Yves Girard (c.1971) and John Reynolds (c.1974).  I don't have the 
references to hand.

Hope this helps!


> I have already read all available online documentation.
> In logic one has: forall x forall y = forall y forall x.

This is not the case in the second-order lambda calculus, because the 
order of the type lambdas is clearly significant:

(.) :: \/a. \/b. \/c. (a->b) -> (b->c) -> (a->c)

is clearly different from

(.') :: \/c \/b. \/a. (a->b) -> (b->c) -> (a->c)

although the two are in some sense equivalent.


> Doesn't haskell 98 allow in place updating e.g; for records?

[see next message]

> Thanks

You're welcome!

> Jan

--KW 8-)

-- 
: Keith Wansbrough, MSc, BSc(Hons) (Auckland) ------------------------:
: PhD Student, Computer Laboratory, University of Cambridge, England. :
:  (and recently of the University of Glasgow, Scotland. [><] )       :
: Native of Antipodean Auckland, New Zealand: 174d47' E, 36d55' S.    :
: http://www.cl.cam.ac.uk/users/kw217/  mailto:[EMAIL PROTECTED]     :
:---------------------------------------------------------------------:




Reply via email to