Before TaPL comes in the mail and I'm "forced" to actually read about this, I'm working on a type inference algorithm. It's always kind of fun to pretend that all that research out there doesn't exist and become a pioneer. You'll either come up with an inferior approach that makes some trade-offs that the real pioneers didn't think of, or you'll come up with the same thing they did, but you'll understand it really well, because you thought of it. The latter happens to me a lot.
Anyway, here's my algorithm. It considers all types to be sets, nothing more, nothing less. It also considers type classes to be sets of types (sets of sets). That way, you can use the same algorithm to do type inference and type class inference. It also lets you trivially do type class classes, whatever those are.
The two operations it works with are "does" (subset) and "in" (element). Let's look at how it would translate some simple code into type equations:
sub fact($x) { # fact: a --> b if $x == 0 { 1 } # ==: c,c --> Bool | Eq[c] else { $x * fact($x - 1) } # -: d,d --> d | Num[d] # *: e,e --> e | Num[e] }
# conditional a does c 0 in c c in Eq Bool does Bool # if branch 1 in b # else branch a does d 1 in d d in Num d does e a does e e does b
Re:Nitpicks and comments
luqui on 2005-09-15T17:35:38
> Instead of
> d does e
> I get
> d does a
> b does e
> (from the call to fact).
That's right, good eye.
> 1 in a in Num
> 1 in b in Num
[...]
> which may not be as tight as you'd like but
> expresses the constraints reasonably. It allows,
> for instance,
> a == [1..5]
Actually it doesn't. "a in Num" means that a is a ring. If you say 4 + 3 (which are both in a here), you get 7, which is not in a, so a is not in Num.
What I'm currently stumpted on is if you say fact(3). The caller is supposed to provide the instances present in the constraints. But 3 is in Int, Float, Bigint, Z_4 (integers mod 4), etc. Which one do you pick? Also, what do you pick for your return value? Why would you have to provide the Eq[c] instance, when you don't even know what c represents.
But, upon looking at the constraints, this is all you can really infer without monotypes. So I'm hoping there's a way around it.