Scala 错误的前向引用
Scala wrong forward reference
我正在完成一些练习:Scala 中的函数式编程特别是问题 5.2。问题是我从答案中拼凑出以下代码。
sealed trait Stream[+A]
{
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
case Cons(hs, _) if n == 1 => cons(h(), empty)
case _ => empty
}
}
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream{
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head , () => tail)
}
def empty[A]: Stream[A] = Empty
def apply[A](as: A*): Stream[A] =
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}
我在 REPL 中得到以下内容:
<console>:10: error: not found: type A
def take(n: Int): Stream[A] = this match {
^
<console>:11: error: not found: value Cons
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
^
<console>:11: error: not found: value cons
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
^
<console>:12: error: not found: value Cons
case Cons(hs, _) if n == 1 => cons(h(), empty)
^
<console>:12: error: not found: value cons
case Cons(hs, _) if n == 1 => cons(h(), empty)
^
<console>:13: error: not found: value empty
case _ => empty
^
这段代码有 2 个问题:
- 未明确指定
empty
和 cons
方法位于伴随对象中 Stream
要解决此问题,您需要 import Stream._
到您的 class:
sealed trait Stream[+A] {
import Stream._
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => cons(hs(), empty)
case _ => empty
}
}
或者您需要明确指定:
sealed trait Stream[+A] {
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
case _ => Stream.empty
}
}
- 使用
case class Cons
中t
和h
的变量名代替hs
和ts
的绑定变量。
当你这样做时:
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
你是说你想将 case class 参数分别提取为 hs
和 ts
并在下一个代码块中使用它们。在 class 的情况下,它们是否被称为 h
和 t
并不重要,它们将被分配您在匹配中指定的名称。
解决这两个问题,您的代码应该可以编译(我亲自使用 Scala 2.11.5 和 Java 1.7 对其进行了测试,但我认为这无关紧要):
sealed trait Stream[+A] {
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
case _ => Stream.empty
}
}
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream{
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head , () => tail)
}
def empty[A]: Stream[A] = Empty
def apply[A](as: A*): Stream[A] =
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}
我正在完成一些练习:Scala 中的函数式编程特别是问题 5.2。问题是我从答案中拼凑出以下代码。
sealed trait Stream[+A]
{
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
case Cons(hs, _) if n == 1 => cons(h(), empty)
case _ => empty
}
}
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream{
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head , () => tail)
}
def empty[A]: Stream[A] = Empty
def apply[A](as: A*): Stream[A] =
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}
我在 REPL 中得到以下内容:
<console>:10: error: not found: type A
def take(n: Int): Stream[A] = this match {
^
<console>:11: error: not found: value Cons
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
^
<console>:11: error: not found: value cons
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
^
<console>:12: error: not found: value Cons
case Cons(hs, _) if n == 1 => cons(h(), empty)
^
<console>:12: error: not found: value cons
case Cons(hs, _) if n == 1 => cons(h(), empty)
^
<console>:13: error: not found: value empty
case _ => empty
^
这段代码有 2 个问题:
- 未明确指定
empty
和cons
方法位于伴随对象中Stream
要解决此问题,您需要 import Stream._
到您的 class:
sealed trait Stream[+A] {
import Stream._
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => cons(hs(), empty)
case _ => empty
}
}
或者您需要明确指定:
sealed trait Stream[+A] {
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
case _ => Stream.empty
}
}
- 使用
case class Cons
中t
和h
的变量名代替hs
和ts
的绑定变量。
当你这样做时:
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
你是说你想将 case class 参数分别提取为 hs
和 ts
并在下一个代码块中使用它们。在 class 的情况下,它们是否被称为 h
和 t
并不重要,它们将被分配您在匹配中指定的名称。
解决这两个问题,您的代码应该可以编译(我亲自使用 Scala 2.11.5 和 Java 1.7 对其进行了测试,但我认为这无关紧要):
sealed trait Stream[+A] {
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
case _ => Stream.empty
}
}
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream{
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head , () => tail)
}
def empty[A]: Stream[A] = Empty
def apply[A](as: A*): Stream[A] =
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}