Haskell“类型变量`a0'是模糊的”错误

时间:2016-05-11 13:46:15

标签: haskell functional-programming

我正在尝试为这个系列写一个函数。

Cos Series

代码在这里:

fact x = product [1..x]

cosSeries x l = sum[(helperOfCos x i pointer)
        |i<-[0..l], i `mod` 2 == 0, pointer<-[0..l]]


helperOfCos x i p = if p `mod` 2 == 0
        then x**i/(fact i)
        else -(x**i)/(fact i)

我收到了这个错误:

*Main> cosSeries 2 2

<interactive>:2:1:
No instance for (Integral a0) arising from a use of `cosSeries'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
  instance Integral Int -- Defined in `GHC.Real'
  instance Integral Integer -- Defined in `GHC.Real'
  instance Integral GHC.Types.Word -- Defined in `GHC.Real'
In the expression: cosSeries 2 2
In an equation for `it': it = cosSeries 2 2

<interactive>:2:11:
No instance for (Num a0) arising from the literal `2'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
  instance Num Double -- Defined in `GHC.Float'
  instance Num Float -- Defined in `GHC.Float'
  instance Integral a => Num (GHC.Real.Ratio a)
    -- Defined in `GHC.Real'
  ...plus three others
In the first argument of `cosSeries', namely `2'
In the expression: cosSeries 2 2
In an equation for `it': it = cosSeries 2 2

我无法理解stackoverflow中类似问题的解决方案。

你能帮我解决这个错误吗?

谢谢..

1 个答案:

答案 0 :(得分:5)

始终添加签名,以获得更好的错误。

fact :: Int -> Int
fact x = product [1..x]

cosSeries :: Double -> Int -> Double
cosSeries x l = sum[(helperOfCos x i pointer)
        |i<-[0..l], i `mod` 2 == 0, pointer<-[0..l]]


helperOfCos :: Double -> Int -> Int -> Double
helperOfCos x i p = if p `mod` 2 == 0
        then x^i / fromIntegral (fact i)
        else -(x^i) / fromIntegral (fact i)

这里的问题是缺少最后两个fromIntegral。实际上,fact i返回了一个整数类型(因为mod以上强制i是积分的),但/需要浮点类型。

如果没有转换,我们会得到一个具有不可满足约束的类型:

> :t cosSeries 
cosSeries :: (Fractional a, Integral a) => a -> a -> a

另请注意,fact会很快生成非常大的数字并导致溢出。您可以使用Integer代替Int来阻止这种情况,或者重新编写代码,以避免在每一步计算阶乘。