9

I am trying to infer the type of the following expression:

let rec fix f = f (fix f)

which should be given the type (a -> a) -> a

After using the bottom up algorithm (described in generalizing hindley-milner type inference algorithms) with the added rule below:

           a1, c1 |-BU e1 : t1     B = fresh var
---------------------------------------------------------
a1\x, c1 U {t' == B | x : t' in A} |-BU let rec x = e1 : t

i am left with the following type: t1 -> t2

and the following constraints:

t0 = fix
t1 = f
t2 = f (fix f)
t3 = f
t4 = fix f
t5 = fix
t6 = f

t3 = t1
t3 = t4 -> t2
t5 = t0
t5 = t6 -> t4
t6 = t1

I cant see how these constraints can be solved such that i am left with the type (a -> a) -> a. I hope it is obvious for someone to see were i am going wrong.

full source code here

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • Please note that `let rec` should be simply `let`, otherwise you're just defining a function `rec :: ((a -> b) -> a) -> (a -> b) -> b`. – Ptharien's Flame May 14 '12 at 02:21
  • 2
    @Ptharien'sFlame sorry code example wasnt in haskell but an ML style language. –  May 14 '12 at 11:12
  • Okay, it's just that you had the question tagged with "haskell" so I assumed that was the language you were working with. Sorry! – Ptharien's Flame May 14 '12 at 18:05

1 Answers1

9

Shouldn't there be a t7 for the first fix f? These give the constraints:

t7 = t2
t0 = t1 -> t7

From that you should be able to deduce that t4 = t2 and then t0 = (t2 -> t2) -> t2.

Sjoerd Visscher
  • 11,840
  • 2
  • 47
  • 59
  • 1
    you were spot on, i wasn't constraining B to t in the rule above! –  May 13 '12 at 22:15