首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个F#引用在运行时失败?

为什么这个F#引用在运行时失败?
EN

Stack Overflow用户
提问于 2021-05-05 01:53:59
回答 3查看 133关注 0票数 1

我正在尝试理解为什么这个F#脚本在运行时失败。

代码语言:javascript
复制
#r "nuget: FsToolkit.ErrorHandling, 2.2.0"

open System
open FsToolkit.ErrorHandling

<@@ async {
        return!
          asyncResult {
            return! (Result.Ok true)
          }
} @@>

错误:

代码语言:javascript
复制
$ dotnet fsi ./Quotations.fsx

System.InvalidOperationException: Could not bind function AsyncResultBuilder.Source in type FsToolkit.ErrorHandling.AsyncResultCEExtensions
   at Microsoft.FSharp.Quotations.PatternsModule.fail@1118[a](Type ty, String nm, Unit unitVar0) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1118
   at Microsoft.FSharp.Quotations.PatternsModule.bindModuleFunctionWithCallSiteArgs$cont@1110(Type ty, String nm, Type[] argTypes, Type[] tyArgs, Unit unitVar) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1169
   at Microsoft.FSharp.Quotations.PatternsModule.bindModuleFunctionWithCallSiteArgs(Type ty, String nm, FSharpList`1 argTypes, FSharpList`1 tyArgs) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1105
   at Microsoft.FSharp.Quotations.PatternsModule.u_ModuleDefn@1572-1.Invoke(FSharpList`1 argTypes, FSharpList`1 tyargs) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1576
   at Microsoft.FSharp.Quotations.PatternsModule.u_constSpec@1636.Invoke(FSharpList`1 argTypes, FSharpList`1 tyargs) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1636
   at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1492.Invoke(BindingEnv env) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1501
   at Microsoft.FSharp.Primitives.Basics.List.mapToFreshConsTail[a,b](FSharpList`1 cons, FSharpFunc`2 f, FSharpList`1 x) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 239
   at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc`2 mapping, FSharpList`1 x) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 247
   at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1492.Invoke(BindingEnv env) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1493
   at Microsoft.FSharp.Quotations.PatternsModule.u_Expr@1508-2.Invoke(BindingEnv env) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\quotations.fs:line 1508
   at Microsoft.FSharp.Primitives.Basics.List.mapToFreshConsTail[a,b](FSharpList`1 cons, FSharpFunc`2 f, FSharpList`1 x) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 239
   at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc`2 mapping, FSharpList`1 x) in F:\workspace\_work\1\s\src\fsharp\FSharp.Core\local.fs:line 247
...

这是F#报价的问题吗?或者是FsToolkit.ErrorHandling包?

请解释错误消息以及发生错误的原因。

EN

回答 3

Stack Overflow用户

发布于 2021-05-05 03:43:33

正如上面的回答所说的,它可能是由于引用中的过载解决而发生的。但您可以通过将builder包装在一个函数中来解决这个问题,然后将该函数传递给一个报价:

代码语言:javascript
复制
let returnResult =
  asyncResult {
    return! (Result.Ok true)
  }
      
let quotation =
  <@@
    async {
      return! returnResult
    }
  @@>
  
...

在这里,returnResult将是ValueWithName内部的一个ValueOp,返回returnResult FSharpFunc

票数 3
EN

Stack Overflow用户

发布于 2021-05-05 03:01:22

我认为简短的答案是两者的结合。以下是我所能确定的:

  • F#编译器将asyncResult表达式拆分为对AsyncResultCEExtensions.Source的调用。参见解释here和源代码here.
  • There是Source方法的几个不同的重载,因此引用机制有一些复杂的逻辑来试图找出选择哪一个。参见源代码here.
  • Unfortunately,引用机制无法确定编译器使用的是哪个Source方法,因此它会失败,并显示您粘贴的错误消息:Could not bind function AsyncResultBuilder.Source in type FsToolkit.ErrorHandling.AsyncResultCEExtensions.

有人可能会认为这是引用机制中的一个错误,因为它无法理解编译器的意图。但是,我不确定F#是否保证每个可能的合法表达式都是可引用的(因此您会遇到半友好的错误消息)。对F#编译器和核心库内部有更多了解的人可能会更有前途。

票数 1
EN

Stack Overflow用户

发布于 2021-05-06 23:51:30

这对我很有效(请注意,我使用的是return而不是return!。我猜类型推断需要更多的信息,但我不会进一步研究。

代码语言:javascript
复制
<@@ async {
    return!
      asyncResult {
        return (Result.Ok true)
      }
} @@>

更新

经过进一步的调查,似乎有一个bug。我打开了一个新的问题System.InvalidOperationException - Could not bind function *** in type

问题似乎是计算表达式库使用了以下几个方面的组合:

将生成器重载划分为单独的源成员(如在other answers)

  • Using a filled)

  • Other (s:#seq<_>)

  • Evaluation a弱类型,
  • 中提到的那样,整体需要是类型不正确的源成员重载,即modules
  • Overloading a quotation

中的源(s:#seq<_>)

  • Evaluation

其中之一的任何更改都可以解决问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67389799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档