Haskell函数digitSum部分输入下栈溢出,求原因及规避方法
Haskell digitSum函数栈溢出问题分析与修复
你的digitSum函数出现栈溢出的核心原因是终止条件设置错误。原函数的第一个模式digitSum _ 1 = 1仅处理了x=1的情况,但当递归到x=0时,会不断触发第二个模式:
digitSum base 0 = (0 `mod` base) + digitSum base (0 `div` base)
也就是0 + digitSum base 0,这会形成无限递归,持续占用栈空间直到溢出。
那些能正常运行的输入(比如10 15、11 121),是因为它们的递归路径最终会到x=1,触发终止条件停止递归;而像10 456这类输入,递归路径是456→45→4→0,到x=0后就陷入无限递归,最终导致栈溢出。
修复方案
把终止条件改为处理x=0的情况——当x被base除到0时,已经没有更多数字需要求和:
digitSum :: Integer -> Integer -> Integer digitSum _ 0 = 0 digitSum base x = (x `mod` base) + digitSum base (x `div` base)
这样递归到x=0时就会返回0,求和过程正常终止,不会出现栈溢出。
如果确实需要保留x=1的特殊处理逻辑,也可以补充对应的模式,但必须确保x=0的情况被优先覆盖:
digitSum :: Integer -> Integer -> Integer digitSum _ 0 = 0 digitSum _ 1 = 1 digitSum base x = (x `mod` base) + digitSum base (x `div` base)
内容的提问来源于stack exchange,提问作者Juraj Pangrác
相关产品推荐
相关产品推荐

