是什么导致 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
但随后您将它与 Fractional
(6.10
、...)一起使用,方法是 map
将其覆盖在您的 leftSide
和 rightSide
现在 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)
我正在使用 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
但随后您将它与 Fractional
(6.10
、...)一起使用,方法是 map
将其覆盖在您的 leftSide
和 rightSide
现在 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)