Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 检查函数是否声明为递归函数_F# - Fatal编程技术网

F# 检查函数是否声明为递归函数

F# 检查函数是否声明为递归函数,f#,F#,是否可以检查函数是否声明为递归函数,即使用let rec 我有一个memoize函数,但它不适用于任意递归函数。如果用户使用这样的函数调用它,我想给出一个错误。(请随时告诉我这是否是处理F#中错误的糟糕方法)F#代码被编译为.NET公共中间语言。F#rec关键字只是对F#编译器的一个提示,它使正在定义的标识符在函数范围内可用。因此,我认为在运行时无法确定函数是否声明为递归函数 但是,您可以使用System.Diagnostic.StackTraceclass()在运行时获取和分析堆栈帧。但是访问

是否可以检查函数是否声明为递归函数,即使用let rec

我有一个memoize函数,但它不适用于任意递归函数。如果用户使用这样的函数调用它,我想给出一个错误。(请随时告诉我这是否是处理F#中错误的糟糕方法)

F#代码被编译为.NET公共中间语言。F#
rec
关键字只是对F#编译器的一个提示,它使正在定义的标识符在函数范围内可用。因此,我认为在运行时无法确定函数是否声明为递归函数


但是,您可以使用
System.Diagnostic.StackTrace
class()在运行时获取和分析堆栈帧。但是访问堆栈信息会对性能产生重大影响(我假设您的记忆功能是为了提高程序性能)。此外,由于编译器可以进行优化,程序的调试版本和发布版本中的堆栈信息可能会有所不同

我认为这不能以一种明智和全面的方式来完成

不过,您可能需要重新评估您的问题。我假设你的函数对递归函数“不起作用”,因为它只回写第一个调用,而所有的递归调用都转到非回写的函数?根据您的情况,这可能不是一件坏事

记忆化以记忆换取速度。在大型系统中,如果只关心最终结果,您可能不想支付记录中间结果的费用。所有这些词典都是随着时间的推移而积累起来的

然而,如果您特别关心记忆递归函数,那么您可以以一种便于记忆的方式显式地构造它。看


所以我的答案是,memoize函数根本不应该关心递归。如果用户想要记忆一个递归函数,那么他就要理解其中的权衡,并以一种允许中间调用被记忆的方式构造函数(如果他需要的话)

什么是“任意递归函数”?你能给出一些你要问的代码例子吗?对于尾部递归函数,堆栈跟踪方法不是会失败得很惨吗(更糟糕的是,默认情况下只会在发布模式下失败)?除非尾部递归在堆栈上留下足够的信息,您可以判断您正在执行递归?可能是的,正如我所说的,堆栈跟踪方法将显著影响性能感谢您的解释。很高兴知道“rec”实际上只是一个编译器提示(尽管信息可能存储在某个地方,并使用反射找到)。StackTrace解决方案很有趣。我假设由于F#的非循环性质,如果函数在调用堆栈中出现两次,那么它必须是递归的。不,我不会真的用它来优化——我主要只是感兴趣和好奇,并试图帮助自己更好地学习和理解这门语言:)