没有(Num a)的实例来自使用"+" Haskell [英] No instance for (Num a) arising from a use of ‘+’ Haskell
问题描述
我不知道为什么这行不通:
I can't figure out why this won't work:
final' :: [a] -> a
final' lst = foldl(\accum x -> accum - accum + x) 0 lst
我总是收到错误没有实例(数字a)",这是由于使用"+"引起的
I always get the error No instance for (Num a) arising from a use of ‘+’
推荐答案
该问题与函数本身无关,但与您自己附加的签名无关:
The problem has nothing to do with the function itself, but with the signature you attach to it yourself:
final' :: [a] -> a
在这里,您基本上说您的final'
函数将对 any a
起作用.因此,我可以-如果需要的话-将String
以及IO ()
实例或其他任何东西加在一起.但是,现在Haskell检查您的函数,并注意到您执行了加法(+) :: Num a => a -> a -> a
,其操作数为x
,其类型为a
.就像(+)
的签名已经说过的那样,两个操作数都应该具有 same 类型,并且该类型应该是Num
的实例.
Here you basically say that your final'
function will work for any a
. So I could - if I wanted - add String
s together, as well as IO ()
instances, or anything else. But now Haskell inspects your function, and notices that you perform an addition (+) :: Num a => a -> a -> a
, with as right operand x
, which has type a
. Like the signature for (+)
already says, both operands should have the same type, and that type should be an instance of Num
.
您可以通过使签名更具限制性来解决问题:
You can solve the problem by making the signature more restrictive:
final' :: Num a => [a] -> a
final' lst = foldl(\accum x -> accum - accum + x) 0 lst
实际上,我们还可以泛化签名的一部分,并使其适用于任何Foldable
:
In fact we can also generalize a part of the signature, and let it work for any Foldable
:
final' :: (Num a, Foldable f) => f a -> a
final' lst = foldl(\accum x -> accum - accum + x) 0 lst
但是我们可以摆脱accum
,因为从自身中减去一个数字通常会导致为零(四舍五入问题除外):
We can however get rid of the accum
, since subtracting a number from itself, will usually result in zero (except for rounding issues, etc.):
final' :: (Num a, Foldable f) => f a -> a
final' = foldl (const id) 0
现在我们摆脱了(+)
(和(-)
),但仍然需要使用Num
.原因是您将0
用作初始累加器,并且在列表为空的情况下,我们将返回0
和0 :: Num n => n
.
Now we got rid of (+)
(and (-)
), but still need to use Num
. The reason is that you use 0
as initial accumulator, and in case of an empty list, we thus will return 0
, and 0 :: Num n => n
.
这篇关于没有(Num a)的实例来自使用"+" Haskell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!