Recursion 标准ML斐波那契溢出

Recursion 标准ML斐波那契溢出,recursion,functional-programming,sml,smlnj,ml,Recursion,Functional Programming,Sml,Smlnj,Ml,我一直在学习一些函数式编程,并决定选择ML作为我的工具。我学ML才几天,可能总共花了5-6个小时来解决一些问题。不管怎样,关于我的问题 通常,在学习一门语言时,我会问一些问题,以了解语法和操作。所以我一直在研究一个需要阶乘函数的问题。虽然我经常遇到溢出错误,但通常在其他语言中解决这个问题时,我会添加一些备忘录或依靠标准库来避免它,但我对ML的缺乏经验使备忘录看起来很陌生 我尝试过使用尾部递归,但没有骰子: fun fact_helper (0,r:int) = r | fact_helper (

我一直在学习一些函数式编程,并决定选择ML作为我的工具。我学ML才几天,可能总共花了5-6个小时来解决一些问题。不管怎样,关于我的问题

通常,在学习一门语言时,我会问一些问题,以了解语法和操作。所以我一直在研究一个需要阶乘函数的问题。虽然我经常遇到溢出错误,但通常在其他语言中解决这个问题时,我会添加一些备忘录或依靠标准库来避免它,但我对ML的缺乏经验使备忘录看起来很陌生

我尝试过使用尾部递归,但没有骰子:

fun fact_helper (0,r:int) = r
| fact_helper (n:int,r:int) = fact_helper (n-1,n*r);

fun factorial n:int = fact_helper(n, 1);
即使使用标准库:

foldl op * 1 (List.tabulate(100, fn x => x + 1))
将导致溢出


我在谷歌上搜索过,但ML似乎很少有讨论或社区。因此,我想我的问题是什么是一个示例,或者我应该如何以记忆的方式编写阶乘函数,或者通常如何避免ML中的溢出。

问题是您的实现依赖于
Int.Int
数据类型,SML/NJ上的数据类型限制为31位(请参阅)。这意味着可以计算的值有一个上限。如果您试图超过该限制,则会出现
溢出
异常:

- (Option.valOf Int.maxInt) + 1;

uncaught exception Overflow [overflow]
  raised at: <file stdIn>

请注意,整数溢出和堆栈溢出都会导致相同的异常,这可能会让人非常困惑。@sepp2k您是对的,尽管我认为在SML/NJ中甚至不可能出现堆栈溢出。用谷歌搜索很难:)事实上,我错了。根据标准,溢出例外是专门针对算术溢出的,我想可能导致堆栈溢出的实现是被禁止的——至少它们没有例外。啊,我甚至没有想到int溢出。这个错误有点含糊不清,但也是我的错,因为我没有研究原语int类型是如何处理的。我感谢你的帮助!
open IntInf;

fun fact_helper (0,r:int) = r
  | fact_helper (n:int,r:int) = fact_helper (n-1,n*r);

fun factorial n:int = fact_helper(n, 1);

factorial 50;
(* 30414093201713378043612608166064768844377641568960512000000000000 *)