gpt4 book ai didi

recursion - 如何使重试函数尾递归?

转载 作者:行者123 更新时间:2023-12-03 08:25:36 24 4
gpt4 key购买 nike

我有一个类似于 Result 的有区别的联合。 Scott's Railway Oriented Programming 中使用的类型.为简单起见,这里稍微简化一下:

type ErrorMessage = ErrorMessage of string

type ValidationResult<'a> =
| Success of 'a
| Error of ErrorMessage

我有对应的模块 ValidationResult包含作用于这些 ValidationResult 的函数s,其中之一是递归 retryable允许参数 f: unit -> 'a 的函数, 如果 stdin 被再次调用(例如从 ValidationResult 读取)是 Error :
module ValidationResult

let doubleMap success error = function
| Success x -> success x
| Error e -> error e

let rec retryable errorHandler f =
let result = f ()
let retry e =
errorHandler e
retryable errorHandler f
doubleMap id retry result

但它不是尾递归的,我想将其转换为尾递归。我怎样才能做到这一点?

最佳答案

F# 编译器以两种不同的方式编译尾递归函数。

  • 如果函数简单(直接调用自身),则编译成循环
  • 如果尾递归涉及多个不同的函数(甚至函数值),则编译器使用 .tail IL 指令进行尾调用。这也是一个尾调用,但由 .NET 运行时处理,而不是由 F# 编译器消除。

  • 在您的情况下, retryable函数已经是尾递归的,但它是第二种。丹尼尔的回答使它足够简单,以至于它成为第一种。

    但是,您可以保留该功能,它将是尾递归的。唯一需要注意的是编译器不会生成 .tail默认情况下在 Debug模式下指令(因为它弄乱了调用堆栈),因此您需要显式启用它(在项目选项中,选中“生成尾调用”)。

    关于recursion - 如何使重试函数尾递归?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37005324/

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