【问题标题】:F# inline function: instance member constraint failF# 内联函数:实例成员约束失败
【发布时间】:2018-07-12 10:30:42
【问题描述】:
我尝试将member constraint 与我的inline 函数一起使用,如下所示:
let inline extractMessageAsync
(envelope: ^env when ^env:
(member GetBodyAsync: unit-> Task<'a>)) =
envelope.GetBodyAsync()
但我收到以下错误:
根据此程序点之前的信息查找不确定类型的对象。在这个程序点之前可能需要一个类型注释来约束对象的类型。这可能会解决查找问题。
虽然我知道编译器需要有关此类型的更多信息,但我不明白为什么,特别是因为它适用于 static member 约束,适用于 (+) 或 (*) 等运算符。
【问题讨论】:
标签:
generics
f#
constraints
【解决方案1】:
你可以像这样写一个更短更通用的版本:
let inline GetBodyAsync x = (^a: (member GetBodyAsync: unit -> ^b) x)
现在写GetBodyAsync相当于写fun x -> x.GetBodyAsync(),不管方法的返回类型如何。
用法:
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
【解决方案2】:
试试这个:
let inline extractMessageAsync<'a, ^env
when ^env: (member GetBodyAsync: unit-> Task<'a>)>
(envelope: ^env) =
(^env: (member GetBodyAsync: unit-> Task<'a>) envelope)