只要绝对值大于0.001,该函数就应返回该值。
但是,我的代码似乎有一些类型错误,我只是不知道如何解决。我已经尝试过将所有类型都更改为Double,但是仍然无法正常工作。
fac :: Int -> Int
fac n = if (n == 0) then 1 else n * fac (n-1)
cos :: Double -> Double
cos x = sum [cos| k <- [0..],
let cos = (-1) * (x^(2*k) `div` fac (2*k)) ,
abs (cos) > 0.001]
这是错误:
•无法将预期的类型“ Double”与实际类型“ Int”
匹配•在“ div”的第二个参数中,即“ fac(2 * k)”
答案 0 :(得分:6)
这里基本上有两个问题:
div
仅用于整数除法(即采用整数输入,并通过舍入产生整数输出)。您需要(/)
进行浮点除法。fac
返回一个Int
,在进行除法运算之前,必须将其显式转换为浮点数。 (许多语言将自动从整数类型转换为浮点类型,但Haskell不会。)您可以使用fromIntegral
进行转换。解决了这两个问题,但除此之外,我们得到了:
fac :: Int -> Int
fac n = if (n == 0) then 1 else n * fac (n-1)
cos :: Double -> Double
cos x = sum [cos| k <- [0..],
let cos = (-1) * (x^(2*k) / fromIntegral (fac (2*k))) ,
abs (cos) > 0.001]
此类型检查(尽管还有其他问题)从最重要到最不重要依次进行:
abs cos <= 0.001
在一次迭代中,对于以后的所有迭代将继续如此,并停止迭代。但事实并非如此。您说要从k
中抽出[0..]
,所以它将从整个列表中抽出k
-永远不会完成。您可能更喜欢takeWhile
。k
上失去了指数-1
!fac (2*k)
的调用都必须重新计算以前作为中间结果所做的所有阶乘。而您的x^(2*k)
会重复一些工作(尽管程度要小得多)。cos
非常令人困惑。尽管从技术上讲它不会使程序错误出错,但我还是会避免使用它。我把它留给您玩,以探索Haskell并学习如何自己解决这些问题,我认为这完全在您在此处显示的能力之内!