Haskell中Generator-Selector模式求平方根陷入死循环问题排查
问题排查:Haskell Generator-Selector模式死循环问题
嘿,我一眼就揪出了导致死循环的核心问题——你的generator函数根本没在构建列表结构!
问题根源
Haskell是惰性求值语言,列表的生成必须依赖(:)(cons运算符)来逐步产出元素。但你当前的generator实现是:
generator :: (Double -> Double) -> Double -> [Double] generator f a = generator f (f a)
这是纯无限递归调用,它没有产生任何列表元素,只是不断调用自身。当selector试图匹配a : b : r的列表模式时,永远等不到第一个元素被计算出来,直接陷入死循环。
修正方案
你需要让generator每次计算出下一个值后,用(:)把它加入列表,再递归生成后续元素。根据你预期的序列(从next 5 2 = 2.25开始),修正后的generator可以写成:
generator :: (Double -> Double) -> Double -> [Double] generator f a = nextVal : generator f nextVal where nextVal = f a
或者更简洁的版本:
generator :: (Double -> Double) -> Double -> [Double] generator f a = f a : generator f (f a)
验证修正效果
现在调用selector 0.1 (generator (next 5) 2),generator会逐步生成序列:[2.25, 2.23611111111111, 2.2360679779158,...]selector会首先比较2.25和2.236111...的差值(约0.0138),这个值小于0.1,所以直接返回2.23611111111111,完全符合你的预期。
额外说明
你的selector和next函数实现是没问题的——selector的模式匹配和终止条件逻辑正确,next的牛顿迭代公式也完全符合平方根近似的计算逻辑,问题完全出在generator没有产出列表元素上。
内容的提问来源于stack exchange,提问作者Jakob Nielsen
相关产品推荐
相关产品推荐

