以下工作正常:
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
我不明白。
我应该纠正什么?你能解释我为什么会遇到这些错误吗?
已解决:我使用/
更改了div
。
是否有更惯用和/或简洁的方法来编写相同的算法?
答案 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