Eclipser
Eclipser

Reputation: 45

Couldn't match expexted type Double with actual Int

I tried to calculate ch value without using cosh function.

ch :: Double -> Int -> Double
ch' :: Double -> Int -> Integer -> Double -> Double

fac :: Integer -> Integer
fac 0 = 1
fac k | k > 0 = k * fac (k-1)

taylor :: Double -> Int -> Double
taylor x n = ((x^2*n))/ (2*(fac n))

ch x iter = ch' x iter 0 1
ch' x iter n sum | iter == fromIntegral n = sum
                 | iter /= fromIntegral n = ch' x iter (n+1) (sum + (taylor x n))

But I have error:

Couldn't match expected type `Double` with actual type `Integer`
In the second argument of `(*)`, namely `n`
In the first argument of `(/)`, namely `((x ^ 2 * n))`

and

Couldn't match expected type `Double` with actual type `Integer`
In the second argument of `(*)`, namely `fac n`
In the first argument of `(/)`, namely `(2 *(fac n))`

I guess I tried to divide Double, but I've got Integer. How I can solve this problem?

Thanks a lot!

Upvotes: 1

Views: 1736

Answers (1)

bheklilr
bheklilr

Reputation: 54078

The problem is that the arithmetic operators +, *, and - have the type

Num a => a -> a -> a

Where the Num a has to be the same a on both sides of the operator. Both Double and Integer implement Num, but you can not add them directly. Instead, you have to convert your values to the correct type. Since you're returning a Double from taylor, I'm guessing that you want to convert your Integer values to Double values. You can do this easily with fromInteger (which is actually a function in the Num typeclass):

taylor x n = (x^2 * fromInteger n) / (2 * fromInteger (fac n))

Notice that you have to convert both Integer values in this computation. If this looks a bit cluttered to you, you can always use a where clause:

taylor x n = (x^2 * n')/ (2 * facn)
    where
        n' = fromInteger n
        facn = fromInteger $ fac n

Upvotes: 3

Related Questions