Scala: methods in trait can't use methods from companion object

两盒软妹~` 提交于 2020-07-02 03:10:52

问题


When I try to compile the following I get: "not found: value cons" and "not found: value empty" for the take and drop method definitions.

Somehow the trait doesn't "see" the companion object?

I'm using IntelliJ IDEA, in case that matters.

import scala.annotation.tailrec

object Run extends App {
  sealed trait StreamRed[+A] {
    def headOption: Option[A] = this match {
      case Empty => None
      case Cons(h,t) => Some(h())
    }

    def toList: List[A] = {
      @tailrec
      def toListRec(stream: StreamRed[A], accumulated: List[A]): List[A] = this match {
        case Cons(h,t) => toListRec(t(), h()::accumulated)
        case _ => accumulated
      }
      toListRec(this, List()).reverse
    }

    def take(n: Int): StreamRed[A] = this match {
      case Cons(h, t) if n > 1 => cons(h(), t().take(n - 1))
      case Cons(h, _) if n == 1 => cons(h(), empty)
      case _ => empty
    }

    @tailrec
    def drop(n: Int): StreamRed[A] = this match {
      case Cons(_,t) if n > 0 => t().drop(n-1)
      case _ => empty
    }

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

  object StreamRed {
    def cons[A](hd: => A, tl: => StreamRed[A]): StreamRed[A] = {
      lazy val head = hd
      lazy val tail = tl
      Cons(() => head, () => tail)
    }

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

    def apply[A](as: A*): StreamRed[A] =
      if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))
  }
}

回答1:


Companions can see each other's members in the sense that access modifiers are not a problem.

class A {
  private def foo: Unit = ()

  A.bar 
}
object A {
  private def bar: Unit = ()

  (new A).foo
}

is ok on contrary to

class A {
  private def foo: Unit = ()

  B.bar 
}
object B {
  private def bar: Unit = ()

  (new A).foo
}

(But if you replace private with private[this] the former won't work either.)

But this doesn't mean that namespaces are imported automatically.

class A {
  private def foo: Unit = ()

  import A._
  bar
}
object A {
  private def bar: Unit = ()

  val a = new A
  import a._
  foo
}

is ok on contrary to

class A {
  private def foo: Unit = ()

  bar
}
object A {
  private def bar: Unit = ()

  foo
}

Anyway a method has to know its this.



来源:https://stackoverflow.com/questions/59662424/scala-methods-in-trait-cant-use-methods-from-companion-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!