经过一定数量的递归调用后,如何停止函数?

时间:2019-04-14 13:47:10

标签: haskell recursion

我需要计算一个名为happy的函数的递归调用。我得到一个提示,我可以使用辅助功能来做到这一点。我只是想不通,我应该如何实现它。递归达到1000次调用后应该停止。

digits :: Integer -> [Integer]
digits x 
 | x < 1     = []
 | x == 1    = [1]
 | otherwise = x `mod` 10 : digits (x `div` 10)

squareSum :: [Integer] -> Integer
squareSum (x:xs) = sum (map (^2) (x:xs))

happy :: Integer -> Bool
happy x
 | x == 1 = True
 | otherwise = (happy . squareSum . digits) x

happyNumbers :: [Integer]
happyNumbers = filter happy [1..500]

digits函数获取一个整数,并创建一个包含数字的列表。

squareSum函数对这些数字进行平方运算,并对它们进行汇总。

happy是它反复调用自身的函数,但是当它达到1000个调用时,我需要停止它。

1 个答案:

答案 0 :(得分:3)

据我所知,快乐数字是happy生成的序列收敛为1的那些,因此您可以返回True,而不快乐则是那些顺序永远持续下去。您想返回False,但是现在您的代码只是在不满意的数字上循环。 (例如,happy 1返回True,但happy 2挂起。)

执行此操作的通常方法是引入一个用作倒数计时的新参数。得到的提示是要引入辅助功能happy',这样您就不必更改happy的类型签名。尝试定义:

happy :: Integer -> Bool
happy x = happy' 1000 x

happy' :: Integer -> Integer -> Bool
happy' countDown x
   | x == 1 = True
   | otherwise = (happy' (countDown - 1) . squareSum . digits) x

到目前为止,此“解决方案”仍将永远运行,但是现在您有了一个countDown参数!您应该能够添加一个新的受保护的大小写,以检查countDown是否已过期以返回False