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

前端 未结 1 573
梦毁少年i
梦毁少年i 2021-01-25 23:08

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

相关标签:
1条回答
  • 2021-01-25 23:44

    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.

    0 讨论(0)
提交回复
热议问题