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