Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are function parameters not polymorphic in Algorithm W (or Haskell)?

I am implementing Algorithm W for a toy language. I came across a case that I imagined would type check, but doesn't. I tried the same in Haskell, and to my surprise it didn't work there either.

> (\id -> id id 'a') (\x -> x)
Couldn't match type ‘Char -> t’ with ‘Char’
Expected type: Char -> t
Actual type: (Char -> t) -> Char -> t

I assumed that id would be polymorphic, but it doesn't seem to be. Note that this example works if id is defined using let instead of passed as an argument:

let id x = x in id id 'a'
'a'
:: Char

Which makes sense when looking at the inference rules for Algorithm W, since it has a generalization rule for let expressions.

But I wonder if there is any reason for this? Couldn't the function parameter be generalized as well so it can be used polymorphically?

like image 248
waxwing Avatar asked Jul 22 '21 07:07

waxwing


People also ask

What are polymorphic functions in Haskell?

Parametric polymorphism In Haskell, this means any type in which a type variable, denoted by a name in a type beginning with a lowercase letter, appears without constraints (i.e. does not appear to the left of a =>). In Java and some similar languages, generics (roughly speaking) fill this role.

What is it called when the type of a function contains one or more type variables?

A type that contains one or more type variables is called polymorphic.

What is nil Haskell?

The Nil constructor is an empty list. It contains no objects. So any time you're using the [] expression, you're actually using Nil . Then the second constructor concatenates a single element with another list.


Video Answer


1 Answers

The problem with generalizing lambda-bound variables is that it requires higher-rank polymorphism. Take your example:

(\id -> id id 'a')

If the type of id here is forall a. a -> a, then the type of the whole lambda expression must be (forall a. a -> a) -> Char, which is a rank 2 type.

Besides that technical point there is also an argument that higher rank types are very uncommon, so instead of inferring a very uncommon type it might be more likely that the user has made a mistake.

like image 158
Noughtmare Avatar answered Nov 11 '22 14:11

Noughtmare