首页 > 解决方案 > 在 Haskell 中计算近似值的生成器、选择器模式

问题描述

我正在尝试实现一个生成器,选择器模式来近似计算haskell中的平方根

我的生成器如下所示:

generator :: (Double -> Double) -> Double -> [Double]
generator f a           = generator f (f a)

我的选择器:

selector :: Double -> [Double] -> Double
selector eps (a : b : r)
  | abs(a - b) <= eps   = b
  | otherwise           = selector eps (b : r)

和近似函数:

next :: Double -> Double -> Double
next n x                = (x + n/x) / 2

像这样调用selector 0.1 (generator (next 5) 2) 应该给我...(next 5( next 5 (next 5 2)))[2.25, 2.23611111111111, 2.2360679779158,...]因为我的 eps 参数是 0.1abs(a - b) <= eps在第一次执行时应该是真的,2.23611111111111结果给我。然而,我确实以无限循环结束。

有人可以向我解释这些功能的实现有什么问题吗?

提前致谢

标签: haskell

解决方案


这个定义

generator f a = generator f (f a)

永远不会生成任何列表元素:相反,它会陷入无限递归。你可能想要

generator f a = a : generator f (f a)

a是第一个元素,然后是我们使用递归生成的所有其他元素。

避免将未评估的 thunk 放入列表中也可能是有益的。为避免这种情况,可以使用

generator f a = a `seq` (a : generator f (f a))

所以a早期评估。这在您的代码中应该无关紧要,因为选择器会在生成 thunk 后立即对其进行评估。


推荐阅读