Christopher Diggins wrote:
> In Combinator theory the combinator SII (a.k.a. M or Mockingbird)
> applies a function to itself.
> \a.aa
> I notice that SML 98 and F# can't infer the type (e.g. let M a = a a ).
> What languages can infer the type? What language features are required
> to express the type?
> Why don't the type systems to those languages simply output something
> like:
> M : 'a.('a -> 'b) -> 'b
I guess this is supposed to express the type
forall b. (forall a. a -> b) -> b
This is indeed (one) possible solution, but with its nested quantifier,
it is a so-called higher-rank polymorphic type. Plain ML does not allow
such types, because type inference for them is undecidable in general.
Some extensions to ML - i.e. Le Botlan/Remy's MLF, or Haskell with GHC
extensions - allow it if you supply sufficient type annotations. But the
meta-theory of such extensions is pretty involved, and more or less an
open research area.
Plain ML only supports prenex polymorphism, where all quantifiers are in
front. This is said to hit a "sweet spot" in type system design, because
it is expressive enough for most practical problems but still allows
complete type inference.
To type self application of an argument x in that system, you have to
solve the type equation
a = a->a'
To see why, assume x:t for some type t.
Because we apply something to x, we know t=t1->t2.
And because the argument also has type t, we need t1=t, i.e. t1=t1->t2.
The only solution is a recursive type, a fixed point of the above
equation. Usually this is written mu a.a->a'.
Such so-called equi-recursive types are not hard to add to ML, but the
thing is: You Do Not Want Them. Just recently, Andrew Bromage gave a
nice illustration why, on the Haskell-Cafe list:
http://www.haskell.org/pipermail/haskell-cafe/2006-December/020074.html
OCaml used to have recursive type inference in its very first versions,
but it was quickly banned to an explicit switch by popular demand.
Whenever you really need recursive types in ML, you can always express
them by explicit wrapping into an auxiliary algebraic datatype.
- Andreas