检查函数是否被声明为递归

时间:2015-08-31 13:04:19

标签: f#

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

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

2 个答案:

答案 0 :(得分:5)

F#代码编译为.NET公共中间语言。 F#rec关键字只是对F#编译器的一个提示,它使得在函数范围内定义的标识符可用。所以我相信没有办法在运行时发现函数声明是递归的。

但是,您可以使用System.Diagnostic.StackTrace类(https://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx)在运行时获取和分析堆栈帧。但访问堆栈信息会对性能产生重大影响(我假设您的memoization函数用于加速程序性能)。在程序的Debug和Release版本中,堆栈信息也可能不同,因为编译器可以进行优化。

答案 1 :(得分:2)

我认为不能以合理和全面的方式完成。

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

Memoization交换内存以提高速度。在大型系统中,如果您只关心最终结果,则可能不想支付记忆中间结果的成本。随着时间的推移,所有这些词典都会加起来。

如果您特别关注memoizing一个递归函数,那么您可以以一种有助于memoization的方式显式地构造它。请参阅linked threads

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