简体   繁体   中英

Haskell type signature pi

I am very new to Haskell and functional programming.

I want to approximate pi with a programm. My code works but only without the type-signature. Yet the task is to write a list-comprehension that fits the given type-signature so I probably have to change sth in my list-comprehension.

pi_approx :: Int -> Double

pi_approx n = sqrt (6 * (sum [1 / x^2 | x <- [1..n]])) 

The reason that this does not work with the signature Int -> Double is because functions like (*):: Num a => a -> a -> a and sqrt:: Floating a => a -> a require that the operand(s) and the result all have the same type.

This thus means that if n is an Int , then x in x <- [1..n] is also an Int , and since the type signature of (^) is (^):: (^):: (Integral b, Num a) => a -> b -> a , it means that x ^ 2 has the same type as x , and this is thus an Int as well.

The problem that now arises is that (/):: Fractional a => a -> a -> a requires the type to a member of the Fractional typeclass, and an Int is is not Fractional .

We can make use of fromIntegral:: (Integral a, Num b) => a -> b to convert a value from a type that is a member of the Integral typeclass to value with a type that is a member of the Num typeclass.

We thus can fix this problem with:

pi_approx :: Int -> Double
pi_approx n = sqrt (6 * (sum [1 /  (x^2) | x <- [1..n]]))

if x can be large, it makes sense, as @dfeuer says , to convert x to a double before calculating the square:

pi_approx :: Int -> Double
pi_approx n = sqrt (6 * (sum [1 /  x^2 | x <- [1..n]]))

This then produces:

Prelude> pi_approx 1
2.449489742783178
Prelude> pi_approx 2
2.7386127875258306
Prelude> pi_approx 10
3.04936163598207
Prelude> pi_approx 20
3.094669524113704
Prelude> pi_approx 100
3.1320765318091053
Prelude> pi_approx 200
3.136826306330968
Prelude> pi_approx 1000
3.1406380562059946

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM