Newsgroups: comp.lang.functional
Path: utzoo!censor!geac!nixtdc!doug
From: doug@nixtdc.uucp (Doug Moen)
Subject: Re: Type Inference in ML (LML, actually)
Message-ID: <1991Jan19.135716.22591@nixtdc.uucp>
Reply-To: doug@nixtdc.UUCP (Doug Moen)
Organization: Siemens Nixdorf
References: <54161@eerie.acsu.Buffalo.EDU> <4353@undis.cs.chalmers.se> <6784@uqcspe.cs.uq.oz.au> <3603@bruce.cs.monash.OZ.AU> <1991Jan16.225903.2540@comp.vuw.ac.nz>
Date: Sat, 19 Jan 91 13:57:16 GMT

>In article <3603@bruce.cs.monash.OZ.AU>, mmcg@bruce.cs.monash.OZ.AU
>(Mike McGaughey) writes:
>|> There *is* an anomaly in the LML type inference algorithm - one which
>|> has recently prevented my use of the language for some very elegant
>|> continuation based solutions to problems.  The simplest form of the
>|> problem is that the expression
>|> 
>|> 	let x = hd o hd in x
>|> 
>|> will typecheck properly - to (List (List *a))->*a) - whereas
>|> 
>|> 	(\x.x o x) hd
>|> 
>|> will not.  The problem with the second expression seems to be that the
>|> inference algorithm erroneously expects both of the 'x' values in the
>|> x o x to have the same type signature, when in fact it is only the _form_
>|> of the signature that should be shared (perhaps a new set of type
>|> variables should be created for each occurrence of x, and then unified
>|> in the normal way).  Thus the type of x in the expression is given as
>|> (*a->*a).

In article <1991Jan16.225903.2540@comp.vuw.ac.nz>, brian@comp.vuw.ac.nz
(Brian Boutel) writes:
>This ... is quite normal Hindley/Milner typing, and other functional
>languages behave the same way. It is usually expressed by saying that
>the type variables associated with lambda-bound variables are non-generic.
>
>Indeed it is the reason why functional languages need the let (or where)
>syntax. In all respects other than type inference, let a = b in c is
>equivalent to (\a.c)b. ...
>
>The type given to \x.x o x  is Forall t. (t -> t) -> (t -> t), but it
>would appear that a more general type is  Forall T,t. (T t -> t) -> (T(T
>t) -> t), where T is a type constructor variable, e.g T could
>instantiate to List or Tree. etc. Unfortunately, quantification over
>type constructors is second order, and undecidable.

In the latest issue of Lisp and Symbolic Computation (3, 1990),
R. Ghosh-Roy presents a new type-inference system based on conjunctive
types.  His system finds more general types, and can typecheck
a larger set of programs, than the Hindley/Milner system.  His system
is decidable and semantically sound for all types.  As far as I can tell,
'let a = b in c' is completely equivalent to '(\a.c)b' in his system.

The GR system gives '\x.x o x' the type '((*a->*b) + (*b->*c)) -> (*a->*c)'.
The + means type conjunction.  This type can be read as meaning:
  the first occurrence of 'x' in the function has type (*a->*b)
  the second occurrence of 'x' in the function has type (*b->*c)

Under GR, the expression (\x.x o x)(hd) is well typed.  Given:
  (\x.x o x) : ((*a->*b) + (*b->*c)) -> (*a->*c)
  hd : (List *d)->*d
the unification algorithm is able to find the type assignments
  *a = List(List *e)
  *b = List(*e)
  *c = *e
which results in (\x.x o x)(hd) being assigned the type List(List *e)->*e.

So ...
Is conjunctive type inference as good as it seems?
Can we expect a new family of functional languages with conjunctive type
systems to appear?  Can SML (with its module system) and Haskell (with its
type classes) be cleanly extended to use conjunctive types?
-- 
Doug Moen
{mnetor,alias,geac,torsqnt,lsuc}!nixtdc!doug
77 Carlton #1504, Toronto, Ontario, Canada M5B 2J7
