我必须编写一个简单的 pi 近似值,我做到了并且它工作正常,但在任务中它说要编写一个标题为“pi_approx::Int -> Double”的函数。
我的代码:
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))
但是,我的函数在没有“pi_approx::Int -> Double”的情况下工作正常,但是当我尝试使用此声明时,我总是收到类型错误:
pi_approx.hs:10:14:错误:
- 无法将预期类型
Double' 与实际类型
Int' 匹配 - 表达式中: (+) (6/(x * x)) (pi2_approx (x - 1)) 表达式中: 如果 x/= 1 那么 (+) (6/(x * x)) (pi2_approx (x - 1)) 别的 (6/(1 * 1)) 在‘pi2_approx’的方程中: pi2_近似x = 如果 x/= 1 那么 (+) (6/(x * x)) (pi2_approx (x - 1)) 别的 (6/(1 * 1)) | 10 | 10那么 (+) (6/(x*x)) (pi2_approx(x-1)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我尝试以各种方式使用 fromIntegral,如果我在没有声明的情况下运行该函数,我会检查解决方案的类型,即:“(Floating a, Eq a) => a”
据我了解 Double 应该是 Floating 的一个实例,所以我不明白为什么它无法编译。
我对 haskell 很陌生,似乎我不理解数据类型和约束的核心概念。不过,我似乎找不到有关该主题的任何简单且良好的文档/解释。也许这里有人可以根据这个例子帮助我理解:)
最佳答案
因为x
是一个Int
,因此x * x
也是一个Int
,并且你不能使用 Int
表示 (/)::Floating a => a -> a -> a
。
您需要将其转换为Double
,例如使用 fromIntegral :: (Integral a, Num b) => a -> b
:
pi2_approx :: Int -> Double
pi2_approx 1 = 6
pi2_approx x = 6 / <strong>fromIntegral</strong> (x*x) + pi2_approx (x-1)
对于大量迭代,它给出的结果接近于 π2:
Prelude> sqrt (pi2_approx 10000)
3.1414971639472147
关于haskell - Haskell 中数据类型的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72390984/