AshleyYakeley / Truth

Changes and Pinafore projects. Pull requests not accepted.
https://pinafore.info/
GNU General Public License v2.0
32 stars 0 forks source link

Polymorphic recursion #205

Closed AshleyYakeley closed 1 year ago

AshleyYakeley commented 1 year ago

Infer type of let rec f = seq (f 3) end in f Expected: a -> a Found: a -> (a | Integer). This type is sound, but is not the principal type.

AshleyYakeley commented 1 year ago

Consider:

fixf = fn f => let rec x = f x end in x;
rf = fn r => seq (r 3);
rr = fixf rf;

Inferred types:

These inferences are correct.

AshleyYakeley commented 1 year ago

The key code is this:

data AbstractResult ts a =
    forall t. MkAbstractResult (TSNegWitness ts t)
                               (UnifierExpression ts (t -> a))

abstractResult ::
       forall ts a. AbstractTypeSystem ts
    => TSVarID ts
    -> TSOpenExpression ts a
    -> TSOuter ts (AbstractResult ts a)

This is correct when used for lambda abstractions, where the type of the function domain is negative. But it's incorrect when used for recursive lets, where the types of all bindings are positive.

AshleyYakeley commented 1 year ago

let f = ... f ... f ... f in f

Need to calculate a positive type T that subsumes to all of T1, T2, T3 etc.

AshleyYakeley commented 1 year ago

Simple approach: given negative type Ta from abstraction and positive type Tr from value, find best positive type T such that:

Example: rf: (Integer -> Any) -> a -> a

AshleyYakeley commented 1 year ago

No, because

both fail.

AshleyYakeley commented 1 year ago

Wait, just pick T = Tr.

AshleyYakeley commented 1 year ago
r = let x = Just x in x;
f = fn x => Just x;

gives

AshleyYakeley commented 1 year ago
AshleyYakeley commented 1 year ago
AshleyYakeley commented 1 year ago

Test: let rec f: T = f end; rec v = f v end in v

AshleyYakeley commented 1 year ago

Inverse subsumption P- -> Q+ (rigid) to a- -> a+ (free)?

AshleyYakeley commented 1 year ago

Apparently polymorphic recursion inference isn't decideable (LPTK/simple-sub#94), and we can already do it with type signatures, so we won't be doing this.

AshleyYakeley commented 1 year ago

This doesn't seem to be working even with type signatures.

AshleyYakeley commented 1 year ago

OK, this is fixed now.