Reputation: 4787
I try to use member constraint
with my inline
function like this:
let inline extractMessageAsync
(envelope: ^env when ^env:
(member GetBodyAsync: unit-> Task<'a>)) =
envelope.GetBodyAsync()
But I get the following error:
Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
Although I understand that compiler needs more info about this type, I don't understand why, especially since it works just fine with static member
constraints for operators like (+)
or (*)
etc.
Upvotes: 3
Views: 143
Reputation: 10624
You can write a shorter and more generic version like this:
let inline GetBodyAsync x = (^a: (member GetBodyAsync: unit -> ^b) x)
Now writing GetBodyAsync
is the equivalent of writing fun x -> x.GetBodyAsync()
regardless of the return type of the method.
Usage:
open System.Threading.Tasks
type A() =
member this.GetBodyAsync() = Task.FromResult 1
type B() =
member this.GetBodyAsync() = async { return 2 }
A() |> GetBodyAsync |> fun x -> x.Result // 1
B() |> GetBodyAsync |> Async.RunSynchronously // 2
Upvotes: 2
Reputation: 3476
try this:
let inline extractMessageAsync<'a, ^env
when ^env: (member GetBodyAsync: unit-> Task<'a>)>
(envelope: ^env) =
(^env: (member GetBodyAsync: unit-> Task<'a>) envelope)
Upvotes: 2