没有(Num a)的实例来自使用"+" Haskell [英] No instance for (Num a) arising from a use of ‘+’ Haskell

查看:49
本文介绍了没有(Num a)的实例来自使用"+" 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 Strings 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用作初始累加器,并且在列表为空的情况下,我们将返回00 :: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆