没有使用'+'Haskell引起的(Num a)实例

时间:2018-04-17 11:35:39

标签: haskell

我无法弄清楚为什么这不起作用:

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

我总是得到错误没有使用'+'

引起的(Num a)实例

1 个答案:

答案 0 :(得分:6)

问题与功能本身无关,但是您自己附加签名

final' :: [a] -> a

这里你基本上说你的final'功能适用于任何 a。所以我可以 - 如果我想 - 将String加在一起,以及IO ()个实例,或其他任何东西。但是现在Haskell会检查你的函数,并注意到你执行了一个加法(+) :: Num a => a -> a -> a,并使用了类型为x的右操作数a。就像(+)已经说明的签名一样,两个操作数都应该具有相同的类型,并且该类型应该是Num的实例。

您可以通过使签名更具限制性来解决问题:

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

事实上,我们也可以概括部分签名,让它适用于任何Foldable

final' :: (Num a, Foldable f) => f a -> a
final' lst = foldl(\accum x -> accum - accum + x) 0 lst

然而,我们可以摆脱accum,因为从自身中减去一个数字,通常会导致零(除了舍入问题等):

final' :: (Num a, Foldable f) => f a -> a
final' = foldl (const id) 0

现在我们摆脱了(+)(和(-)),但仍然需要使用Num。原因是您使用0作为初始累加器,如果是空列表,我们将返回00 :: Num n => n