Anyone know what the problem with this code is?
let rec Foo(a,b) =
match a () with
| None -> Some(b)
| Some(c) -> Some(Foo(c,b))
Here’s the compiler error:
“Type mismatch. Expecting a ‘a but given a ‘a option The resulting type would be infinite when unifying ”a’ and ”a option'”
Let’s try to reproduce how the compiler tries to infer types here.
“Ok, so I see
a ().amust be a function fromunitto some type, I don’t know which one yet. I’ll call it'a.”“The result of
a ()is matched withNone/Somepatterns. So'amust be a'b optionandchas the type'b.” (Again,'bstands for an unknown, as of yet, type).“No functions or methods are called on
b(exceptSome, which doesn’t narrow the type down, andFoo, the type of which we don’t know so far). I’ll denote its type by'c.”“
FooreturnsSome(b)in one of the branches, so the return type must be'c option.”“Am I done yet? No, I need to check that all types in the expression make sense. Let’s see, in the
Some(c)case,Some(Foo(c,b))is returned. SoFoo(c,b) : 'c. SinceFooreturns anoption, I know'cmust be'd optionfor some'd, andb : 'd. Wait, I already haveb : 'c, that is,b : 'd option.'dand'd optionhave to be the same type, but this is impossible! There must be an error in the definition. I need to report it.” So it does.