是什么导致 Haskell 中出现这样的类型错误?

What causes a type error like this in Haskell?

我正在使用 Haskell 来评估值表的简单限制。我定义了以下函数:

f :: (Integral a) => a -> a
f x = div 1 $ subtract 6 x

并且在 GHCI 中,我 let leftSide = [5.90, 5.91..5.99]let rightSide = [6.10,6.09..6.01],然后:

GHCI> map f leftSide

哪个吐出这个错误:

<interactive>:50:5
  No instance for (Integral Double) arising from a use of `f'
  Possible fix: add an instance declaration for (Integral Double)
  In the first argument of `map', namely `f'
  In the expression: map f leftSide
  In an equation for `it': it = map f leftSide

将 f 的类型声明更改为 (Integral Double a) => a -> a 会使编译器抱怨“Integral”如何应用于太多类型参数。这是怎么回事?

我想你只是试错了 划分 - 你真的想要 (/) 而不是 div...

你的问题是 div 需要 Integral 类型(例如 Integer):

Prelude> :t div
div :: Integral a => a -> a -> a

但随后您将它与 Fractional6.10、...)一起使用,方法是 map 将其覆盖在您的 leftSiderightSide

现在 GHCi 默认为 Double - 但 Double 不是 Integral 的实例 - 这正是 Haskell 所抱怨的。


你试过的东西不起作用,我猜你想写 (Integral a, Double a) => ... 但最后(如果它能起作用 - 它不会因为 Double 是类型而不是类型 - class) 这和说 f :: Double -> Double 是一样的——这会让你再次出错(因为 Double 没有 div

简而言之:使用 (/) 而不是 div 它应该可以工作:

f :: Fractional r => r -> r
f x = (1 /) $ subtract 6 x

这是您的第一个示例:

Prelude> let leftSide = [5.90, 5.91..5.99]
Prelude> map f leftSide
[-10.000000000000036,-11.111111111111128
,-12.49999999999999,-14.285714285714228
,-16.66666666666653,-19.999999999999716
,-24.999999999999424,-33.33333333333207
,-49.999999999996625,-99.99999999998437]

顺便说一句:如果你使用 point-free,你可以更短

f = (1 /) . (6 -)

或者如果你把它写出来,会更清晰/更易读

f x = 1 / (6 - x)