【发布时间】:2013-11-01 03:45:53
【问题描述】:
我一直在尝试通过构建短程序来学习 Haskell。我对函数式编程领域有些陌生,但已经阅读了大量内容。
我在 Haskell 中有一个相对较短的递归函数,用于使用牛顿法找到函数的根,达到浮点数允许的精度:
newtonsMethod :: (Ord a, Num a, Fractional a) => (a -> a) -> (a -> a) -> a -> a
newtonsMethod f f' x
| f x < epsilon = x
| otherwise =
newtonsMethod f f' (x - (f x / f' x))
where
epsilon = last . map (subtract 1) . takeWhile (/= 1)
. map (+ 1) . iterate (/2) $ 1
当我在 GHCi 中解释并插入 newtonsMethod (\ x -> cos x + 0.2) (\ x -> -1 * sin x) (-1) 时,我得到 -1.8797716370899549,这是牛顿方法对所调用值的第一次迭代。
我的第一个问题很简单:为什么它只递归一次?如果您发现此代码的结构或明显错误有任何潜在的改进,也请告诉我。
我的第二个问题,涉及更多一点,是这样的:是否有一些干净的方法来测试这个函数的父调用,看看它是否无法收敛,并相应地退出?
提前感谢您提供的任何答案!
【问题讨论】:
-
希望您不要将该函数用于精确的小数类型,因为
epsilon的计算永远不会结束。
标签: haskell recursion floating-point calculus