So I want to create my own cosine function using this formula:
The function should return the value as long as its absolute value is greater than 0.001.
However, my code seems to have some type errors that I just don't know how to fix. I've already tried changing all types to Double, but it still doesn't work.
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]
This is the error:
• Couldn't match expected type 'Double' with actual type 'Int'
• In the second argument of 'div', namely 'fac (2 * k)'
There are basically two problems here:
div
is for integer division (ie takes integral inputs, and produces an integral output by rounding down) only. You want (/)
for floating-point division. fac
returns an Int
, which you must explicitly convert to a floating-point number before using in division. (Many languages auto-convert from integral types to floating-point types, but Haskell does not.) You can use fromIntegral
to convert. Fixing these two things but nothing else, we get:
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]
This type-checks, though it has several other problems, in order from most important to least:
abs cos <= 0.001
in one iteration, it will continue to be that for all future iterations, and stop iterating. But it doesn't. You said to draw k
from [0..]
, and so it will draw k
from that entire list -- never finishing. You might like takeWhile
instead. k
on -1
! fac (2*k)
must recompute all the previous factorials it had done as intermediate results; and your x^(2*k)
repeats some work (though to a much lesser extent). cos
is pretty confusing. Although it doesn't technically make the program wrong , I'd avoid it. I leave it to you to have fun exploring Haskell and learning how to fix these problems yourself -- I think it's well within the abilities you've shown here!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.