【问题标题】:scala forward reference extends over definitionscala 前向引用扩展了定义
【发布时间】:2015-10-15 00:52:13
【问题描述】:
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]

sealed trait Stream[+A] {

  def toList: List[A] = {
    val buf = new collection.mutable.ListBuffer[A]
    def go(s: Stream[A]): List[A] = s match {
      case Cons(h, t) =>
        buf += h()
        go(t())
      case _ => buf.toList
    }
    go(this)
  }

  def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = Stream.cons(hd, tl)

  def empty = Stream.empty

  def unfold[A, S](z: S)(f: S => Option[(A, S)]): Stream[A] = f(z) match {
    case Some((h,t)) => cons(h, unfold(t)(f))
    case None => empty
  }

  def take(n: Int): Stream[A] = unfold((this, n)) {
    case (Cons(h, t), 1) => Some((h(), (empty, 0)))
    case (Cons(h, t), n) if n > 1 => Some((h(), (t(), n-1)))
    case (Empty, 0) => None
  }
}

object Stream {

  def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = Cons(() => hd, () => tl)

  def empty[A]: Stream[A] = Empty

  val ones: Stream[Int] = Stream.cons(1, ones)
}

object StreamTest {
  def main(args: Array[String]) {

    //why compile error: forward reference extends over definition of value ones
    /*val ones: Stream[Int] = Stream.cons(1, ones)
    println(ones.take(5).toList)*/

    println(Stream.ones.take(5).toList)
  }
}

为什么编译错误?:前向引用扩展了值的定义

在对对象“流”中, val 个:Stream[Int] = Stream.scons(1, one) 没问题

但在 main 方法中,这是不行的(但是...相同的合成物!)

【问题讨论】:

  • @m-z 请删除主方法中的注释符号(/* */),/*val ones: Stream[Int] = Stream.cons(1, ones) println(ones.take(5).toList)*/

标签: scala


【解决方案1】:

前向引用在Cons[+A]...这行引用:

def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = Cons(() => hd, () => tl)

尝试移动

case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]

进入伴随对象。

【讨论】:

  • Empty, Cons 移动到 object Stream 并更改 Cons => Stream.Cons and Empty => Stream.Empty 以消除编译错误。但没有任何改变
【解决方案2】:

本地 val 不是成员。

对于您的测试代码,请执行以下操作:

object StreamTest extends App {
  //def main(args: Array[String]) {

    //why compile error: forward reference extends over definition of value ones
    val ones: Stream[Int] = Stream.cons(1, ones)
    println(ones.take(5).toList)

    println(Stream.ones.take(5).toList)
  //}
}

block 中的限制用 in the spec here 措辞,其中另一个建议是让它成为 block 中的惰性 val,具有相同的效果。

【讨论】:

  • 它有效!如果没有 main 方法,StreamTest 对象就会运行......我认为可能是extends Applazy val 方法也很有效。块中的限制非常有趣。谢谢!
  • App 让初始化程序从 main 运行,但您保留模板语义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 2016-03-03
相关资源
最近更新 更多