【问题标题】: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 -&gt; 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)
      

      【讨论】:

        猜你喜欢
        • 2011-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-20
        • 2017-12-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多