gpt4 book ai didi

f# - 重试 monad 和零构造

转载 作者:行者123 更新时间:2023-12-01 23:00:24 27 4
gpt4 key购买 nike

我正在尝试使用从我们心爱的堆栈溢出中获取的 Retry Monad:

type RetryBuilder(max, sleep : TimeSpan) = 
member x.Return(a) = a
member x.Delay(f) = f
member x.Zero() = failwith "Zero"
member x.Run(f) =
let rec loop(n) =
if n = 0 then failwith "Failed"
else
try f()
with ex ->
sprintf "Call failed with %s. Retrying." ex.Message |> printfn "%s"
Thread.Sleep(sleep);
loop(n-1)
loop max

我想用它来使我的文件复制代码更加健壮:
let retry = RetryBuilder(3, TimeSpan.FromSeconds(1.))
retry {
System.IO.File.Move("a", "b")
}

现在我注意到它有时会因“零”异常而失败。我试图删除 member x.Zero() = failwith "Zero"但现在我收到一个编译时错误:

This construct can be only used if builder defines a 'Zero' method.



任何想法如何继续?

最佳答案

Lee 建议您可以使用 return ()在否则会抛出的计算结束时,因为它们调用 Zero成员。这是一个很好的技巧 - 但您实际上可以将其直接集成到计算构建器中。
Zero当您的计算结束而不返回时使用成员。您可以将其更改为与 return () 相同的操作:

type RetryBuilder(max, sleep : TimeSpan) = 
member x.Return(a) = ...
member x.Zero() = x.Return( () )

然后你可以只写原始代码,你会得到单元结果:
let retry = RetryBuilder(3, TimeSpan.FromSeconds(1.))
retry {
System.IO.File.Move("a", "b")
}

关于f# - 重试 monad 和零构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23129731/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com