Haskell中3和5的倍数之和低于1000

时间:2016-04-02 14:45:27

标签: function haskell types

以下工作正常:

sdb n = sum [n,n*2..999]
main = print $ sdb 3 + sdb 5 - sdb 15

但它不是那么有效,因为每次调用sdb时它必须总计999次/ n次。 当我重写sdb时:

sdb n = 
    let x = quot 999 n
    in n*x*(x+1)/2

runhaskell整个代码,我得到了一整页错误。总结一下:

... No instance for (Show a0) arising from a use of `print'
... No instance for (Integral a0) arising from a use of `sdb'
... No instance for (Num a0) arising from a use of `-'

我为sdb添加了类型声明:

sdb :: Integer -> Integer

但我又收到了一个错误:

No instance for (Fractional Integer) arising from a use of `/'
    Possible fix: add an instance declaration for (Fractional Integer)
    In the expression: n * x * (x + 1) / 2
    In the expression: let x = quot 999 n in n * x * (x + 1) / 2
    In an equation for `sdb':
        sdb n = let x = quot 999 n in n * x * (x + 1) / 2

我不明白。

  1. 我应该纠正什么?你能解释我为什么会遇到这些错误吗? 已解决:我使用/更改了div

  2. 是否有更惯用和/或简洁的方法来编写相同的算法?

1 个答案:

答案 0 :(得分:0)

这个怎么样:

sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]

修改

对于像999这样的小上限,这将是一种更惯用和简洁的方式,但如果需要更通用的解决方案,则上面的速度太慢。这是一个更好的方法,类似于问题本身,使用“高斯的技巧”来对可被n整除的数字求和:

sumOfMults :: Integral a => a -> a -> a -> a
sumOfMults n1 n2 m = sdb n1 + sdb n2 - sdb (lcm n1 n2) where
  sdb n = let x = m `div` n
          in n * x * (x + 1) `div` 2