Scala Stream [Int] #foldLeft和Stream [Int] #sum给出不同的结果

时间:2012-01-18 02:13:07

标签: scala

这个问题与euler project sum-of-primes, and Stream.view有关,但有一点扭曲。我想计算低于200万的所有素数的总和。我创建了一个素数生成器,定义为:

lazy val primes: Stream[Int] = 2 #:: Stream.from(3).filter(i =>
  primes.takeWhile(j => j * j <= i).forall(i % _ > 0))

我写了两个测试,一个使用Stream [Int] #foldLeft,一个使用Stream [Int] #sum:

 @Test
 def testEuler010a {
   primes.view.takeWhile(_ < 2000000).foldLeft(0L)(_ + _) mustEqual 142913828922L
 }

 @Test
 def testEuler010b {
   primes.view.takeWhile(_ < 2000000).sum mustEqual 142913828922L
 }

testEuler010a为我提供了正确的答案,而testEuler010b没有回答1179908154。我希望Stream[Int]#foldLeft(0L)(_ + _)Stream[Int].sum相同,但事实并非如此。即使我使用toList()实现了Stream,我也会遇到相同的差异。这些方法应该给出相同的结果是不正确的假设吗?

我正在使用Scala 2.9.1.final。

1 个答案:

答案 0 :(得分:11)

问题似乎是溢出。这些给我的结果相同:

(primes map (_.longValue) takeWhile (_ < 2000000)).sum
(primes map (_.longValue) takeWhile (_ < 2000000)).foldLeft(0L)(_ + _)

我认为sumfoldLeft之间的区别在于sum的结果类型与要求的元素类型相同({{3}所要求的}}),但foldLeft可以有不同的结果类型,您可以通过编写0L来实现。