在Haskell的分部,仍然没有得到它

pfe*_*ror 7 int haskell types integer division

我仍然不理解Haskell中的划分.我的第一个目的是定义一个这样的函数:

piApprox :: (Integral a, Fractional b) => a -> b
piApprox n = 4 * sum [ (-1)^k / (2*k + 1) | k <- [0..n] ]
Run Code Online (Sandbox Code Playgroud)

它不起作用.然后,使用签名:

piApprox :: (Fractional a) => Int -> a
Run Code Online (Sandbox Code Playgroud)

但它再次引发了"无法演绎"错误.

如果我在解释器中运行此代码以找出最佳签名,结果是:

Prelude> let piApprox n = 4 * sum [ (-1)^k / (2*k + 1) | k <- [0..n] ]
Prelude> :t piApprox
piApprox :: (Fractional a, Integral a) => a -> a
Run Code Online (Sandbox Code Playgroud)

引发"类型变量`a0'是模糊的"错误.

现在,进行此计算的唯一方法是我可以想到包括Ratio包然后double通过使用转换为fromRational.

import Data.Ratio
piApprox n = (fromRational) $ 4 * sum [ (-1)^k % (2*k + 1) | k <- [0..n] ]
Run Code Online (Sandbox Code Playgroud)

它有效,但我不认为这是最好的方法.

我还认为即使输入和输出类型在签名中也是正确的,中间操作(-1)^k / (2*k + 1)- 放置分区 - 可能是问题,所以我还定义了:

piApprox' :: (Fractional a) => Int -> a
piApprox' n = 4 * sum [ (fromIntegral) $ (-1)^k / (2*k + 1) | k <- [0..n] ]
Run Code Online (Sandbox Code Playgroud)

没有运气.我在这里错过了什么?

Sib*_*ibi 5

这应该工作:

piApprox n = 4 * sum [ fromIntegral ((-1)^k) / fromIntegral (2*k + 1) | k <- [0..n] ]
Run Code Online (Sandbox Code Playgroud)

fromIntegral函数的类型签名为:

(Integral a, Num b) => a -> b

因此它基本上将您的Integral类型转换为Num类型.

的类型(/是:

Fractional a => a -> a -> a,所以你必须提供分数数据.

fromIntegral函数将通过将其转换为Num包含Fractional类型的类型来完全实现此目的.