I know I must be missing something really obvious here. B.GetInstance().Call()
generates the error: Lookup on object of indeterminate type based on information
The quick summary is that in a recursive group (e.g. members in one type, or members of recursive types like we have here) F# reads the declarations in left-to-right top-to-bottom order, followed by the definitions in left-to-right top-to-bottom order. So in this instance when it reaches the definition of A.Call
, it has not yet read the definition of B.GetInstance
and therefore does not (yet!) know that the return type of GetInstance
will be B
.
Keith's answer nails it for this situation, you can provide a type annotation to specify the return type of GetInstance
in its declaration.
See
Forcing F# type inference on generics and interfaces to stay loose
for a deep discussion of what's going on here.
Note also that in your original attempt, you don't need to "cast" (the potentially dynamic operation, using :>
), instead you can just "annotate" (statically declare a type, using :
) to get it to compile. But makes more sense to put the type annotation in the method declaration for GetInstance
(generally, prefer addition annotations to method signatures instead of arbitrary places inside bodies).