haskell - Haskell 中数据类型的混淆

标签 haskell types

我必须编写一个简单的 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/

相关文章:

haskell - 我可以在类型构造函数中强制一个存在量化的参数吗?

c# 类型别名/自定义类型

Haskell 无效类型签名

haskell - 用于生成 Haskell 函数依赖(控制流)图的工具?

haskell - Haskell 中匿名函数的真值表

haskell - haskell中的无限循环? (新手)

generics - 在 Typescript 中创建通用方法装饰器

haskell - 为什么 Haskell 中的 `forever` 是这样实现的?

haskell - 具有零构造函数的代数数据类型有什么意义?

scala - 编译时检查某些属性