- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在特定上下文中更好地理解 F# 重载解析。
我正在编写一个简单的 asyncResult
工作流/计算表达式,以便在与异步工作流结合时更容易使用面向铁路的编程风格的错误处理。我通过在工作流构建器上重载 Bind
方法来做到这一点。这是相当标准的,并在我见过的所有指南中使用(并且也用于例如 Chessie/ErrorHandling.fs )。
我有一个接受 Async<_>
的重载和一个接受 Result<_,_>
的重载。现在,理想情况下,我想要接受 Async<Result<_,_>>
的第三个重载。但是,当我尝试将 let!
或 do!
与返回 Async<'a>
的表达式一起使用时,F# 提示无法确定唯一的重载,因为 Async<_>
和 Async<Result<_,_>>
都适合,当然它们确实适合(尽管一个比另一个更适合) .我似乎能够做到这一点的唯一方法是像 Chessie(上面的链接)一样做并定义一个包装器类型:
type AsyncResult<'a, 'b> = AR of Async<Result<'a, 'b>>
Async<Result<_,_>>
的方法的调用包装在这种新类型中:
asyncResult {
let! foo = funcReturningResultInsideAsync() |> AR
...
}
module AsyncResult =
let liftAsync x =
async { return x }
let pure (value: 'a) : Async<Result<'a, 'b>> =
async { return Ok value }
let returnFrom (value: Async<Result<'a, 'b>>) : Async<Result<'a, 'b>> =
value
let bind (binder: 'a -> Async<Result<'b, 'c>>) (asyncResult: Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
async {
let! result = asyncResult
match result with
| Ok x -> return! binder x
| Error x -> return! Error x |> liftAsync
}
let bindResult (binder: 'a -> Async<Result<'b, 'c>>) (result: Result<'a, 'c>) : Async<Result<'b, 'c>> =
bind binder (liftAsync result)
let bindAsync (binder: 'a -> Async<Result<'b, 'c>>) (asnc: Async<'a>) : Async<Result<'b, 'c>> =
bind binder (Async.map Ok asnc)
type AsyncResultBuilder() =
member __.Return value = pure value
member __.ReturnFrom value = returnFrom value
member __.Bind (asyncResult, binder) = bind binder asyncResult
member __.Bind (result, binder) = bindResult binder result
member __.Bind (async, binder) = bindAsync binder async
let asyncResult = AsyncResultBuilder()
// Usage
let functionReturningAsync () =
async { return 2 }
let errorHandlingFunction () =
asyncResult {
// Error: A unique overload for method 'Bind' could not be determined ...
do! functionReturningAsync()
}
最佳答案
F# 重载解析有很多问题,它在规范中有一些规则,但在实践中它不尊重它们。我厌倦了报告有关它的错误,并看到它们在许多情况下是如何以(废话)“按设计”解决方案关闭的。
您可以使用一些技巧使重载优于另一个。 Builders 的一个常见技巧是将其定义为扩展成员,因此它的优先级较低:
module AsyncResult =
let AsyncMap f x = async.Bind(x, async.Return << f)
let liftAsync x =
async { return x }
let pure (value: 'a) : Async<Result<'a, 'b>> =
async { return Ok value }
let returnFrom (value: Async<Result<'a, 'b>>) : Async<Result<'a, 'b>> =
value
let bind (binder: 'a -> Async<Result<'b, 'c>>) (asyncResult: Async<Result<'a, 'c>>) : Async<Result<'b, 'c>> =
async {
let! result = asyncResult
match result with
| Ok x -> return! binder x
| Error x -> return! Error x |> liftAsync
}
let bindResult (binder: 'a -> Async<Result<'b, 'c>>) (result: Result<'a, 'c>) : Async<Result<'b, 'c>> =
bind binder (liftAsync result)
let bindAsync (binder: 'a -> Async<Result<'b, 'c>>) (asnc: Async<'a>) : Async<Result<'b, 'c>> =
bind binder (AsyncMap Ok asnc)
type AsyncResultBuilder() =
member __.Return value = pure value
member __.ReturnFrom value = returnFrom value
member __.Bind (result, binder) = bindResult binder result
member __.Bind (asyncResult, binder) = bind binder asyncResult
let asyncResult = AsyncResultBuilder()
open AsyncResult
type AsyncResultBuilder with
member __.Bind (async, binder) = bindAsync binder async
// Usage
let functionReturningAsync () =
async { return 2 }
let functionReturningAsynResult () =
async { return Ok 'a' }
let errorHandlingFunction () =
asyncResult {
let! x = functionReturningAsync()
let! y = functionReturningAsynResult()
let! z = Ok "worked"
return x, y, z
}
关于f# - 为什么 F# 不能解决 Async<> 和 Async<Result<>> 之间的过载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47697022/
在我看来,CakePHP 中的对象过载过多。我在我的布局中输出调试:debug($this); 并且我发现了 6 个 HTML 帮助对象实例: [Html] => HtmlHelper Object
Product **products; int numProducts = 0; void setup() { ifstream finput("products.txt"); //g
为什么返回 5,我很好奇这个普通函数比默认参数 one 有更高的优先级。有人可以向我解释一下吗?提前致谢 static void Main(string[] args) { Conso
我现在遇到 mysql 过载的问题,然后当它非常繁忙时,服务器将完全停止响应。我知道我的一个数据库有大量流量,但我该如何处理这个问题。我是否需要一台更好的服务器,或者我是否需要一个不同的数据库引擎。目
由于插入查询的过载,我最近开始遇到一些严重的服务器问题。我们服务器上的所有查询一直以来都得到了优化,但是由于大量的 INSERT 查询,流量再次回升并且 CPU 已达到极限。 我们为访问我们网站的每位
我收到这些错误: circleType.cpp||In function 'std::ostream& operator<<(std::ostream&, circleType&)':| circle
好的,我一直是 inspired to do some head punching .似乎重载 operator& 会导致不小的痛苦。 存在哪些合理的重载情况? (不能说我曾经这样做过......)
RabbitMQ 集群不接受新连接! 连接的套接字数量很少,Rabbitmq 日志中的唯一消息是: ** WARNING ** Mnesia is overloaded 这意味着什么?我该如何解决?
我们可以使用 lombok 来生成 setter,如下所示: @Data //or @Setter public class Test { int a;
我正在尝试将大约 1 GB 大小的文件下载到具有 1 GB RAM 内存的服务器,因此如果我尝试将其下载到变量中(下面的代码),操作系统会因 RAM 过载而终止进程. require LWP::Use
这个简单的程序无法编译。 [使用 XE5 和 D10 进行测试。] program Project10; {$APPTYPE CONSOLE} {$R *.res} uses System.Cla
我得到了这台服务器带有 8GB DDR3 RAM 的 Intel Xeon 四核 E3-1230v2 我发现这台服务器的 CPU 正在耗尽。看起来严重重载。观察“每日进程日志”后,我意识到下面的进程占
问题: 我遇到的问题是我的应用程序运行缓慢,因为我在一个文件 (index.html) 中运行了太多页面(page1.html、page2.html 和 page3.html),重点是让用户决定他/她
我试图以这种方式重载 std::find 函数: include include include "Marker.h" namespace Test { class MarkerConta
我有一个动画和 JS,用于交替 2 个 div 并更改它们的背景图像(来自几十个图像的数组),有点可互换的 div。一切正常,但是当动画运行时我可以看到我的 CPU 处于 100%。起初我认为这可能是
我刚刚重新安装了 Vim,这次我在我的 VIM 配置中添加了一些新插件。问题是,现在,当我对文件进行第一次更改时,VIM 会阻塞并且我的一个 CPU 达到 100% 负载。当我编辑文件时,这种情况也会
我是一名新编码员,正在学习 Marionette 来制作 session 预订应用程序。我已经打听了好几个小时,并且已经敲了我的头好几个小时了。 基本上,问题是这样的,当我添加 session 时,会
我正在尝试在 CloudSim Plus 模拟器中进行水平自动缩放。我需要通过多个虚拟机来扩展应用程序。我正在尝试修改示例 LoadBalancerByHorizontalVmScalingExamp
有没有一种方法可以强制 C# 编译器忽略缺少的对象运算符重载,而是在运行时处理该检查?我问是因为我有一个包含多个对象的容器,这些对象具有类型为 int、string、ushort 等的各种属性。我正在
好的,我有这个查询,它为我提供了 DISTINCT product_series,以及表中的所有其他字段: SELECT pi.* FROM ( SELECT DISTINC
我是一名优秀的程序员,十分优秀!