【问题标题】:Code to compute Stream of primes in Scala在 Scala 中计算素数流的代码
【发布时间】:2020-03-25 12:25:52
【问题描述】:

我从这个 SO post 稍微修改了 Daniel Sobral 的主要 Stream 函数:

def primeStream: Stream[Int] => Stream[Int] =
  s => s.head #:: primeStream(s.tail filter(_ % s.head != 0))

我正在使用它:

primeStream(Stream.from(2)).take(100).foreach(println)

它工作得很好,但我想知道我是否可以通过以下方式摆脱那个讨厌的Stream.from(2)

def primeStream: def primeStream: () => Stream[Int] = 
  () => Stream.from(2)  

def primeStream: Stream[Int] => Stream[Int] =
  s => s.head #:: primeStream(s.tail filter(_ % s.head != 0))

实现:

primeStream().take(100).foreach(println)

但这不起作用。我错过了什么?

我也试过了:

def primeStream: Stream[Int] => Stream[Int] = {
  () => Stream.from(2)
  s: Stream[Int] => s.head #:: primeStream(s.tail filter(_ % s.head != 0))
}

这是行不通的。

这行得通:

def primeStream2(s: Stream[Int] = Stream.from(2)): Stream[Int] =
  s.head #:: primeStream2(s.tail filter(_ % s.head != 0))

但我想了解我错过了什么,以使语法适用于上述更对称的语法,其中有两个并行定义 primeStream

【问题讨论】:

    标签: scala


    【解决方案1】:

    第一次尝试不起作用,因为您尝试使用相同的名称定义 2 个不同的方法。方法不能通过它们的返回类型来区分。此外,除了它们的名称之外,它们似乎完全不相关,因此如果您能够调用其中一个,那么另一个的存在将无关紧要。

    第二次尝试将 2 个不相关且未命名的函数放在同一个代码块中。如果您将第一个函数括在括号中,它将编译,但结果不是您所追求的。

    我完全理解您希望将Stream.from(2) 自动设置为自动,因为如果您传递任何其他内容,例如Stream.from(13),您将不会得到质数的Stream

    只有一个Stream 调用,有几种不同的方法可以得到一个惰性素数序列。这个有点复杂,因为它试图在搜索下一个素数时减少内部迭代的次数。

    val primeStream: Stream[Int] = 2 #:: Stream.iterate[Int](3)(x =>
      Stream.iterate(x+2)(_+2).find(i => primeStream.takeWhile(p => p*p <= i)
         .forall(i%_ > 0)).get)
    

    您还可以使用新的 (Scala 2.13) unfold() 方法来创建 Stream

    val primes = Stream.unfold(List(2)) { case hd::tl =>
      Option((hd, Range(hd+1, hd*2).find(n => tl.forall(n % _ > 0)).get::hd::tl))
    }
    
    

    请注意,自 Scala 2.13 起,Stream 已被弃用,应替换为新的 LazyList

    【讨论】:

      猜你喜欢
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-10-19
      相关资源
      最近更新 更多