gpt4 book ai didi

f# - 重试 F# 中的计算表达式或其他构造

转载 作者:行者123 更新时间:2023-12-05 01:06:48 27 4
gpt4 key购买 nike

我希望能够在 F# 中编写一个计算表达式,如果它抛出异常,它将能够重试操作。现在我的代码看起来像:

let x = retry (fun() -> GetResourceX())
let y = retry (fun() -> GetResourceY())
let z = retry (fun() -> DoThis(x, y))
etc. (this is obviously an astract representation of the actual code)

我需要能够重试每个函数一定的次数,这是我在其他地方定义的。

我在想一个计算表达式可以在这里帮助我,但我不明白它如何帮助我删除将每个右侧显式包装到 Retryable<'T>

我可以看到计算表达式类似于:

let! x = Retryable( fun() -> GetResourceX())
etc.

我知道 Monad 以粗略的方式是包装器类型,但我希望有办法解决这个问题。我知道我可以重载一个运算符,并且有一个非常简洁的语法来将一个操作转换为 Retryable<'T>,但对我来说,这只是让重复/包装更简洁;它还在那里。我可以将每个函数包装成一个 Retryable<'T>,但是再一次,我看不到做文章顶部所做的事情的值(value)(在每个操作上调用重试。至少它非常明确)。

也许计算表达式在这里是错误的抽象,我不确定。关于可以在这里做什么的任何想法?

最佳答案

计算表达式有一些扩展(除了标准的 monadic 特性),它们为您提供了一种很好的方法来做到这一点。

正如你所说,monad 本质上是包装器(例如创建 Retryable<'T> ),具有一些额外的行为。但是,F# 计算表达式也可以定义 Run自动解包值的成员,因此 retry { return 1 } 的结果可以只有一个类型 int .

这是一个例子(构建器在下面):

let rnd = new System.Random()
// The right-hand side evaluates to 'int' and automatically
// retries the specified number of times
let n = retry {
let n = rnd.Next(10)
printfn "got %d" n
if n < 5 then failwith "!" // Throw exception in some cases
else return n }

// Your original examples would look like this:
let x = retry { return GetResourceX() }
let y = retry { return GetResourceY() }
let z = retry { return DoThis(x, y) }

这里是 retry 的定义 build 者。它不是真正的 monad,因为它没有定义 let! (当您在另一个 retry block 中使用使用 retry 创建的计算时,它只会根据需要重试内部 X 次和外部 Y 次)。

type RetryBuilder(max) = 
member x.Return(a) = a // Enable 'return'
member x.Delay(f) = f // Gets wrapped body and returns it (as it is)
// so that the body is passed to 'Run'
member x.Zero() = failwith "Zero" // Support if .. then
member x.Run(f) = // Gets function created by 'Delay'
let rec loop(n) =
if n = 0 then failwith "Failed" // Number of retries exceeded
else try f() with _ -> loop(n-1)
loop max

let retry = RetryBuilder(4)

关于f# - 重试 F# 中的计算表达式或其他构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5941868/

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