No instance for (Num a) arising from a use of ‘+’ Haskell

烂漫一生 提交于 2020-01-30 08:09:15

问题


I can't figure out why this won't work:

final' :: [a] -> a
final' lst = foldl(\accum x -> accum - accum + x) 0 lst

I always get the error No instance for (Num a) arising from a use of ‘+’


回答1:


The problem has nothing to do with the function itself, but with the signature you attach to it yourself:

final' :: [a] -> a

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

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

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

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.



来源:https://stackoverflow.com/questions/49877023/no-instance-for-num-a-arising-from-a-use-of-haskell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!