Closed 0x53A closed 7 years ago
Hi,
Sadly, yes. Here is the ugly case.
type X() =
member this.Num = 0
let xTask : Task<X> = task { return X() }
let badTask =
task {
let! x = xTask
return x.Num + 1
// ^ FS0072: Lookup on object of indeterminate type based on
// information prior to this program point.
}
I think that your example works because of the special inference on record properties (i.e. same reason you could write let f x = x.A + x.B
).
I would be really glad to get rid of unitTask
if I could.
Thanks! I created https://github.com/Microsoft/visualfsharp/issues/3281, let's see what happens.
I looked at the approach in your pull request and in the Query.fsi code linked by Don Syme, and at first I thought it only worked to discriminate between Generic<SpecificType>
and Generic<'a>
, so it wouldn't help with the Task
situation, where we have ParentType
and ChildType<'a>
.
But I was also interested in playing around with using inline constraints more to support arbitrary awaitables, like the ValueTask
type. I found that I could use a fancier version of the old bindGenericAwaitable
to support Bind on any task-like using very similar rules to the C# compiler. With Task<'a>
handled by the builder itself, and this new very generic inline await in an extension member, it seems to work. I tested with the existing test suite, a couple new compilation tests, and with my projects Rezoom and Rezoom.SQL that use this builder.
I also had to do something kind of weird where the inline bind is inside a static class with a generic parameter, otherwise the inference gave up on figuring out the return type in some cases (where you are using the inline Bind
in the context of a non-inline generic function).
This is really abusing the compiler and is probably dependent on unspecified implementation details, but it works too well to avoid. Now, not only is unitTask
obsolete, but we can let!
bind arbitrary task-likes just like we can await
them in C#!
Thanks again for posting about this problem on the FSharp github and finding out about the extension member trick. I had never encountered that technique before.
Nice!
Hi,
thank you for this great builder, I've been using it in a few projects.
Do you remember which code constructs caused the type inference issues and made you add
unitTask
?The reason I ask is that there was some work recently to improve the type inference in the compiler, so maybe this is already solved. If not, I would like to extract a repro and add an issue at https://github.com/Microsoft/visualfsharp.
In a simple test, everything seemed to work, but I do know that the solver sometimes breaks down when code gets more complex:
^^^ this works as expected for me, using TaskBuilder.fs from 6aa7ef6e47caf9f0af56413c4bb6d256763ffbaf