Haskell-在给定类型约束的情况下解决类型错误

时间:2019-11-03 14:37:51

标签: haskell

我正试图在Haskell中实现高斯误差函数的数值近似。

erf :: (Floating a) => a -> a
erf x = 1.0 - poly * (exp ** (-(x ** 2)))
    where p = 0.3275911
          t = 1.0 / (1.0 + p * x)
          a1 = 0.254829592
          a2 = -0.284496736
          a3 = 1.421413741
          a4 = -1.453152027
          a5 = 1.061405429
          poly = t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5))))

尝试加载到GHCI中会引发以下错误:

ghci> :l stats
[1 of 1] Compiling Main             ( stats.hs, interpreted )

stats.hs:2:33: error:
    • Couldn't match expected type ‘a0 -> a0’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          erf :: forall a. Floating a => a -> a
        at stats.hs:1:8
    • In the expression: (x ** 2)
      In the second argument of ‘(**)’, namely ‘(- (x ** 2))’
      In the second argument of ‘(*)’, namely ‘(exp ** (- (x ** 2)))’
    • Relevant bindings include
        poly :: a0 -> a0 (bound at stats.hs:10:11)
        t :: a0 -> a0 (bound at stats.hs:4:11)
        p :: a0 -> a0 (bound at stats.hs:3:11)
        a1 :: a0 -> a0 (bound at stats.hs:5:11)
        a2 :: a0 -> a0 (bound at stats.hs:6:11)
        a3 :: a0 -> a0 (bound at stats.hs:7:11)
        x :: a (bound at stats.hs:2:5)
        (Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)

stats.hs:4:32: error:
    • Couldn't match expected type ‘a0 -> a0’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          erf :: forall a. Floating a => a -> a
        at stats.hs:1:8
    • In the second argument of ‘(*)’, namely ‘x’
      In the second argument of ‘(+)’, namely ‘p * x’
      In the second argument of ‘(/)’, namely ‘(1.0 + p * x)’
    • Relevant bindings include
        t :: a0 -> a0 (bound at stats.hs:4:11)
        p :: a0 -> a0 (bound at stats.hs:3:11)
        a1 :: a0 -> a0 (bound at stats.hs:5:11)
        a2 :: a0 -> a0 (bound at stats.hs:6:11)
        a3 :: a0 -> a0 (bound at stats.hs:7:11)
        a4 :: a0 -> a0 (bound at stats.hs:8:11)
        x :: a (bound at stats.hs:2:5)
        (Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)
Failed, modules loaded: none.
ghci> 

我尝试了函数a部分中对where的各种类型的转换,但都没有用。如何修复此功能?

1 个答案:

答案 0 :(得分:0)

exp :: Floating a => a -> a是带有参数的函数。这样的表达式exp ** (x ** 2)就没有多大意义。

我们可以使用参数exp或更简单的exp (-(x ** 2))来调用exp (-x*x)

erf :: Floating a => a -> a
erf x = 1.0 - poly * exp (-x*x)
    where p = 0.3275911
          t = 1.0 / (1.0 + p * x)
          a1 = 0.254829592
          a2 = -0.284496736
          a3 = 1.421413741
          a4 = -1.453152027
          a5 = 1.061405429
          poly = t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5))))

例如:

Prelude> erf 0
9.999999717180685e-10
Prelude> erf 1
0.8427006897475899
Prelude> erf 2
0.9953221395812188
Prelude> erf 3
0.9999778948511022
Prelude> erf 4
0.9999999845397042