I have to write a simple pi approximation and I did and it works fine, but in the task it says to write a function with the header "pi_approx :: Int -> Double".
My code:
pi_approx x = sqrt (pi2_approx(x))
pi2_approx x =
if x/= 1
then (6 /(x*x)) (pi2_approx(x-1))
else (6/(1*1))
However my function works fine without "pi_approx :: Int -> Double", but when i try to use this declaration I always get the type error:
pi_approx.hs:10:14: error:
- Couldn't match expected type
Double' with actual type
Int' - In the expression: ( ) (6 / (x * x)) (pi2_approx (x - 1)) In the expression: if x /= 1 then ( ) (6 / (x * x)) (pi2_approx (x - 1)) else (6 / (1 * 1)) In an equation for `pi2_approx': pi2_approx x = if x /= 1 then ( ) (6 / (x * x)) (pi2_approx (x - 1)) else (6 / (1 * 1)) | 10 | then ( ) (6 /(x*x)) (pi2_approx(x-1)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I tried to use fromIntegral in various ways and if I run the function without declaration I checked the type of the solution, which is: "(Floating a, Eq a) => a"
As I understand Double should be an instance of Floating so I don´t understand why it wont compile.
I am very new at haskell and it seems I don´t understand the core concept of data types and constraints. I can´t seem to find any simple and good documentation/explanation on the topic though. Maybe someone here can help me understand based on this example :)
CodePudding user response:
because x
is an Int
, hence x * x
is also an Int
, and you can not use an Int
for (/) :: Floating a => a -> a -> a
.
You need to convert this to a Double
, for example with fromIntegral :: (Integral a, Num b) => a -> b
:
pi2_approx :: Int -> Double
pi2_approx 1 = 6
pi2_approx x = 6 / fromIntegral (x*x) pi2_approx (x-1)
For a large number of iterations, it gives a result close to π2:
Prelude> sqrt (pi2_approx 10000)
3.1414971639472147