我正在尝试理解为什么这个F#脚本在运行时失败。
#r "nuget: FsToolkit.ErrorHandling, 2.2.0"
open System
open FsToolkit.ErrorHandling
<@@ async {
return!
asyncResult {
return! (Result.Ok true)
}
} @@>错误:
$ 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包?
请解释错误消息以及发生错误的原因。
发布于 2021-05-05 03:43:33
正如上面的回答所说的,它可能是由于引用中的过载解决而发生的。但您可以通过将builder包装在一个函数中来解决这个问题,然后将该函数传递给一个报价:
let returnResult =
asyncResult {
return! (Result.Ok true)
}
let quotation =
<@@
async {
return! returnResult
}
@@>
...在这里,returnResult将是ValueWithName内部的一个ValueOp,返回returnResult FSharpFunc。
发布于 2021-05-05 03:01:22
我认为简短的答案是两者的结合。以下是我所能确定的:
asyncResult表达式拆分为对AsyncResultCEExtensions.Source的调用。参见解释here和源代码here.Source方法的几个不同的重载,因此引用机制有一些复杂的逻辑来试图找出选择哪一个。参见源代码here.Source方法,因此它会失败,并显示您粘贴的错误消息:Could not bind function AsyncResultBuilder.Source in type FsToolkit.ErrorHandling.AsyncResultCEExtensions.有人可能会认为这是引用机制中的一个错误,因为它无法理解编译器的意图。但是,我不确定F#是否保证每个可能的合法表达式都是可引用的(因此您会遇到半友好的错误消息)。对F#编译器和核心库内部有更多了解的人可能会更有前途。
发布于 2021-05-06 23:51:30
这对我很有效(请注意,我使用的是return而不是return!。我猜类型推断需要更多的信息,但我不会进一步研究。
<@@ async {
return!
asyncResult {
return (Result.Ok true)
}
} @@>更新
经过进一步的调查,似乎有一个bug。我打开了一个新的问题System.InvalidOperationException - Could not bind function *** in type
问题似乎是计算表达式库使用了以下几个方面的组合:
将生成器重载划分为单独的源成员(如在other answers)
中的源(s:#seq<_>)
其中之一的任何更改都可以解决问题。
https://stackoverflow.com/questions/67389799
复制相似问题