We\'re gettin\' hairy here. I\'ve tested a bunch of tree-synchronizing code on concrete representations of data, and now I need to abstract it so that it can run with any so
I have not analyzed the code enough to figure out why, but adding
member internal tree.SyncStep() : unit =
// ^^^^^^
seems to fix it.
EDIT
See also
Why does F# infer this type?
Understanding F# Value Restriction Errors
Unknown need for type annotation or cast
It takes experience to get a very deep understanding of the F# type inference algorithm's capabilities and limitations. But this example seems to be in a class of issues people run into when they do very advanced things. For members of a class, the F# inference algorithm does something like
That may not be exactly right; I don't know it well enough to describe the algorithm, I just have a sense of it. You can always go read the language spec.
What often happens is you get as far as bullet 3 and forcing the inferencer to start trying to concurrently solve/constrain all the method bodies when in fact it's unnecessary because, e.g. maybe some function has an easy concrete fixed type. Like SyncStep is unit->unit, but F# doesn't know it yet in step 3, since the signature was not explicit, it just says ok SyncStep has type "unit -> 'a" for some yet-unsolved type 'a and then now SyncStep is now unnecessarily complicating all the solving by introducing an unnecessary variable.
The way I found this was, the first warning (This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'V') was on the last line of the body of UpdateRenditions at the call to docTree.Compare(). Now I know that Compare() should be unit -> unit. So how could I possibly be getting a warning about generic-ness there? Ah, ok, the compiler doesn't know the return type is unit at that point, so it must thing that something is generic that's not. In fact, I could have added the return type annotation to Compare instead of SyncStep - either one works.
Anyway, I'm being very long-winded. To sum up
Hope that helps!