【发布时间】:2014-01-22 07:02:05
【问题描述】:
我仍然不明白 Haskell 中的划分。我的第一个意图是定义一个这样的函数:
piApprox :: (Integral a, Fractional b) => a -> b
piApprox n = 4 * sum [ (-1)^k / (2*k + 1) | k <- [0..n] ]
它不起作用。然后,使用签名:
piApprox :: (Fractional a) => Int -> a
但它再次引发“无法推断”错误。
如果我在解释器中运行这段代码来找出最好的签名,结果是:
Prelude> let piApprox n = 4 * sum [ (-1)^k / (2*k + 1) | k <- [0..n] ]
Prelude> :t piApprox
piApprox :: (Fractional a, Integral a) => a -> a
引发“类型变量‘a0’不明确”错误。
目前,我能想到的唯一进行此计算的方法是包含Ratio 包,然后使用fromRational 转换为double。
import Data.Ratio
piApprox n = (fromRational) $ 4 * sum [ (-1)^k % (2*k + 1) | k <- [0..n] ]
它有效,但我认为这不是最好的方法。
我还认为即使输入和输出类型在签名中都是正确的,中间操作(-1)^k / (2*k + 1)——除法所在——可能是问题所在,所以我也定义了:
piApprox' :: (Fractional a) => Int -> a
piApprox' n = 4 * sum [ (fromIntegral) $ (-1)^k / (2*k + 1) | k <- [0..n] ]
没有运气。 我在这里错过了什么?
【问题讨论】:
-
您可能是指
Integral,而不是第一行代码中的Integer。 Haskell 中的类型之间没有自动转换,因此由于结果是b类型,因此您需要在某处转换a,例如,使用fromIntegral k而不是k。
标签: haskell types integer int division