开发者

Companion object in Scala isn't associating itself with case class

I'm having some trouble understanding why this code won't work. I got it from 99 Scala Problems in the Binary Trees section (http://aperiodic.net/phil/scala/s-99/). It looks valid to me: the Node object is a companion object to the Node class, and it's adding a constructor for leafs on the tree. But when I try compiling it, I get the following:

<console>:10: error: too many arguments for method apply: (value: T)Node[T] in object Node

    def apply[T](value: T): Node[T] = Node(value, End, End)

If I remove both Ends, I don't get any compile errors, but if I make a Node with a single value I get stuck in an infinite loop. So it looks like apply is constructing more Node objects, and isn't associating itself with the Node class.

Any help is appreciated.

sealed abstract class Tree[+T]
case class Node[+T](value: T, left: Tree[T], right: Tree[T]) extends Tree[T] {
    override def toString = "T(" + value.toString + " " + left.toString + " " + right.toString + ")"
}
case object End extends Tree[Nothing] {
    override def toString = "."
}
object Node {
    def apply[T](valu开发者_开发技巧e: T): Node[T] = Node(value, End, End)
}


Works for me (see below). Have you defined them in the same file?


Welcome to Scala version 2.9.0.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_24).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

sealed abstract class Tree[+T]
case class Node[+T](value: T, left: Tree[T], right: Tree[T]) extends Tree[T] {
    override def toString = "T(" + value.toString + " " + left.toString + " " + right.toString + ")"
}
case object End extends Tree[Nothing] {
    override def toString = "."
}
object Node {
    def apply[T](value: T): Node[T] = Node(value, End, End)
}

// Exiting paste mode, now interpreting.

defined class Tree
defined class Node
defined module End
defined module Node

scala> Node("123")
res0: Node[java.lang.String] = T(123 . .)

scala>

Edit From your comment: it looks like the :load command in the repl interprets each line in the file one by one, you can find the code for that here. However this doesn't work using the REPL since (I believe) each line that is interpreted gets compiled in its own package. See this thread for more details. Perhaps this could be a future enhancement in the REPL. But in principle, there is nothing wrong with your code: using both :paste mode or just compiling with scalac works fine.


scala> case class A(i: Int, i2: Int)
defined class A

scala> object A {
     | def apply(i: Int): A = A(i, i)
     | }
:25: error: too many arguments for method apply: (i: Int)A in object A
       def apply(i: Int): A = A(i, i)

scala> object A {
         def apply(i: Int): A = new A(i, i)
       }
defined module A
warning: previously defined class A is not a companion to object A.
Companions must be defined together; you may wish to use :paste mode for this.

N.B. I couldn't find any enhancement request on JIRA, so I created this issue

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜