I still don't understand the division in Haskell. My first intention was to define a funcion like this:
piApprox :: (Integral a, Fractional b) => a -> b
piApprox n = 4 * sum [ (-1)^k / (2*k + 1) | k <- [0..n] ]
It doesn't work. Then, using the signature:
piApprox :: (Fractional a) => Int -> a
but it raises again the "Could not deduce" error.
If I run this code in the interpreter to find out what signature is the best, the result is:
Prelude> let piApprox n = 4 * sum [ (-1)^k / (2*k + 1) | k <- [0..n] ]
Prelude> :t piApprox
piApprox :: (Fractional a, Integral a) => a -> a
which raises "The type variable `a0' is ambiguous" error.
Right now, the only way to make this calculation that I could think of is including the Ratio package and then converting to double by using fromRational.
import Data.Ratio
piApprox n = (fromRational) $ 4 * sum [ (-1)^k % (2*k + 1) | k <- [0..n] ]
It works, but I don't think that's the best approach.
I also thought that even the input and output types were right in the signature, the intermediate operation (-1)^k / (2*k + 1) -- where the division is placed -- might be the problem, so I also defined:
piApprox' :: (Fractional a) => Int -> a
piApprox' n = 4 * sum [ (fromIntegral) $ (-1)^k / (2*k + 1) | k <- [0..n] ]
with no luck. What am I missing here?
This should work:
piApprox n = 4 * sum [ fromIntegral ((-1)^k) / fromIntegral (2*k + 1) | k <- [0..n] ]
The fromIntegral function has a type signature of :
(Integral a, Num b) => a -> b
So it basically converts your Integral type to Num type.
The type of (/) is:
Fractional a => a -> a -> a, so you have to supply Fractional data to it.
The fromIntegral function will exactly achieve this by converting it to a Num type which includes Fractional types.
Your problem is that you're mixing incompatible number types. You said that n is some Integral (specifically, Integer in this case). k <- [0..n] means that k is the same Integral type. Then you use the / division, which is part of the Fractional class. Which means your result would have to be both Integral and Fractional, and I don't think such a type exists.
The solution would be to convert k to your result type before using it with fromIntegral k.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With