4
votes

What is the relationship between polymorphism's rank and (im)predicativity?

Can rank-1 polymorphism be either predicative or impredicative?

Can rank-k polymorphism with k > 1 be either predicative or impredicative?

My confusions come from:

Why does https://en.wikipedia.org/wiki/Parametric_polymorphism mention predicativity under rank-1 polymorphism? (Seems to me rank-1 implies predicativity)

Rank-1 (prenex) polymorphism

In a prenex polymorphic system, type variables may not be instantiated with polymorphic types.[4] This is very similar to what is called "ML-style" or "Let-polymorphism" (technically ML's Let-polymorphism has a few other syntactic restrictions). This restriction makes the distinction between polymorphic and non-polymorphic types very important; thus in predicative systems polymorphic types are sometimes referred to as type schemas to distinguish them from ordinary (monomorphic) types, which are sometimes called monotypes. A consequence is that all types can be written in a form that places all quantifiers at the outermost (prenex) position. For example, consider the append function described above, which has type

forall a. [a] × [a] -> [a]

In order to apply this function to a pair of lists, a type must be substituted for the variable a in the type of the function such that the type of the arguments matches up with the resulting function type.

In an impredicative system, the type being substituted may be any type whatsoever, including a type that is itself polymorphic; thus append can be applied to pairs of lists with elements of any type—even to lists of polymorphic functions such as append itself. Polymorphism in the language ML is predicative.[citation needed] This is because predicativity, together with other restrictions, makes the type system simple enough that full type inference is always possible.

As a practical example, OCaml (a descendant or dialect of ML) performs type inference and supports impredicative polymorphism, but in some cases when impredicative polymorphism is used, the system's type inference is incomplete unless some explicit type annotations are provided by the programmer.

...

Predicative polymorphism

In a predicative parametric polymorphic system, a type τ containing a type variable α may not be used in such a way that α is instantiated to a polymorphic type. Predicative type theories include Martin-Löf Type Theory and NuPRL.

https://wiki.haskell.org/Impredicative_types :

Impredicative types are an advanced form of polymorphism, to be contrasted with rank-N types.

Standard Haskell allows polymorphic types via the use of type variables, which are understood to be universally quantified: id :: a -> a means "for all types a, id can take an argument and return a result of that type". All universal quantifiers ("for all"s) must appear at the beginning of a type.

Higher-rank polymorphism (e.g. rank-N types) allows universal quantifiers to appear inside function types as well. It turns out that appearing to the right of function arrows is not interesting: Int -> forall a. a -> [a] is actually the same as forall a. Int -> a -> [a].

However, higher-rank polymorphism allows quantifiers to the left of function arrows, too, and (forall a. [a] -> Int) -> Int really is different from forall a. ([a] -> Int) -> Int.

Impredicative types take this idea to its natural conclusion: universal quantifiers are allowed anywhere in a type, even inside normal datatypes like lists or Maybe.

Thanks.

1
By the way, in the future, you can save yourself some heartache (and me a few seconds of effort) by explicitly linking questions you have already read which do not answer your question, and explaining why they aren't answers. (This is also officially recommended, so this is not just a sour grapes request.)Daniel Wagner

1 Answers

6
votes

Can rank-1 polymorphism be either predicative or impredicative?

No, rank-1 polymorphism is always predicative, because any forall quantifiers do not appear as arguments to type constructors, that is, quantifiers are “prenex”.

Can rank-k polymorphism with k > 1 be either predicative or impredicative?

Higher-rank polymorphism is always impredicative; the RankNTypes extension enables impredicative polymorphism only for the (->) constructor, that is, given a type a -> b, a or b may be instantiated with a type containing foralls. We typically refer to such types as higher-rank only when a contains foralls, because (except for TypeApplications) X -> forall t. Y is equivalent to forall t. X -> Y.

General impredicative polymorphism (with the broken ImpredicativeTypes extension) is not supported. For example, you can’t write Maybe (forall a. [a] -> [a]). This is essentially because it’s difficult to automatically determine when to generalise and when to instantiate that quantifier. Fortunately, you can make this explicit using a newtype wrapper to “hide” the impredicativity, or rather, make it clear to the compiler what you want to do about quantifiers, e.g.:

{-# LANGUAGE RankNTypes #-}

newtype ListTransform = ListTransform { unLT :: forall a. [a] -> [a] }

f :: Maybe ListTransform -> [Int] -> [Char] -> ([Int], [Char])
f Nothing is cs = (is, cs)
f (Just (ListTransform t)) is cs = (t is, t cs)
-- or: f (Just lt) is cs = (unLT lt is, unLT lt cs)