[英]What causes a type error like this in Haskell?
I'm playing with Haskell to evaluate simple limits with tables of values. 我正在与Haskell一起使用值表评估简单极限。 I have the following function defined:
我定义了以下函数:
f :: (Integral a) => a -> a
f x = div 1 $ subtract 6 x
and in GHCI, I let leftSide = [5.90, 5.91..5.99]
and let rightSide = [6.10,6.09..6.01]
, then: 在GHCI中,我
let leftSide = [5.90, 5.91..5.99]
, let rightSide = [6.10,6.09..6.01]
,然后:
GHCI> map f leftSide
Which barfs up this error: 哪个阻止了此错误:
<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
Changing my type declaration for f to (Integral Double a) => a -> a
makes the compiler complain about how `Integral' is applied to too many type arguments. 将我的f的类型声明更改为
(Integral Double a) => a -> a
使编译器抱怨“ Integral”如何应用于太多类型参数。 What's going on here? 这里发生了什么?
I think you just tried the wrong division - you really want (/)
not div
... 我认为您只是尝试了错误的除法 -您真的想要
(/)
而不是div
...
your problem is that div
which demands an Integral
type (for example an Integer
): 您的问题是需要
Integral
类型(例如Integer
)的div
:
Prelude> :t div
div :: Integral a => a -> a -> a
but then you use it with a Fractional
( 6.10
, ...) by map
ing it over your leftSide
and rightSide
但是然后通过
map
它map
到您的leftSide
和rightSide
,将它与Fractional
( 6.10
,...) rightSide
now GHCi defaults this to Double
- but Double
is not an instance of Integral
- this is exactly what Haskell is complaining about. 现在GHCI默认这
Double
-但Double
是不是一个实例Integral
-这正是Haskell是抱怨。
the thing you tried does not work and I guess you wanted to write (Integral a, Double a) => ...
but in the end (if it would work - it does not since Double
is type and not a type-class) it would be the same as saying f :: Double -> Double
anyway - which would get you the error again (as there is no div
for Double
) 您尝试过的东西不起作用,我想您想写
(Integral a, Double a) => ...
但是最后(如果可行的话-因为Double
是type而不是type-class,所以没有用)就像说f :: Double -> Double
-这将再次导致您错误(因为Double
没有div
)
To make it short: use (/)
instead of div
and it should work: 简而言之: 使用
(/)
代替div
,它应该可以工作:
f :: Fractional r => r -> r
f x = (1 /) $ subtract 6 x
here is your first example: 这是您的第一个示例:
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]
btw: you can make this shorter if you use point-free: 顺便说一句:如果您使用无点,则可以使它更短 :
f = (1 /) . (6 -)
or a bit cleaner / more readable if you write it out 还是写得更干净/可读性更好
f x = 1 / (6 - x)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.