Case classes and equals

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Case classes and equals

Blair Zajac-3
I was reading the Scala book and the chapter on object equality got into the
hairy details of writing a proper hashCode() and equals() method.  The book then
stated that using case classes removes the need to do all this work.

However, the following code does not compile:

case class Point(val x: Int, val y: Int)

object Color extends Enumeration {
   val red, green, blue = Value
}

case class ColoredPoint(override val x: Int,
                         override val y: Int,
                         val color: Color.Value)
   extends Point(x, y)


test.scala:7: error: implementation restriction: case class ColoredPoint and
case class Point cannot be combined in one object
case class ColoredPoint(override val x: Int,
            ^
one error found


Now looking into case classes, I've only seen case classes derive from a
non-case abstract class, such as the examples with Expr, Val, BinOp, etc.

How would one write Point and ColoredPoint with case classes?

Regards,
Blair


Reply | Threaded
Open this post in threaded view
|

Re: Case classes and equals

David MacIver
On Jan 11, 2008 8:33 PM, Blair Zajac <[hidden email]> wrote:

> I was reading the Scala book and the chapter on object equality got into the
> hairy details of writing a proper hashCode() and equals() method.  The book then
> stated that using case classes removes the need to do all this work.
>
> However, the following code does not compile:
>
> case class Point(val x: Int, val y: Int)
>
> object Color extends Enumeration {
>    val red, green, blue = Value
> }
>
> case class ColoredPoint(override val x: Int,
>                          override val y: Int,
>                          val color: Color.Value)
>    extends Point(x, y)
>
>
> test.scala:7: error: implementation restriction: case class ColoredPoint and
> case class Point cannot be combined in one object
> case class ColoredPoint(override val x: Int,
>             ^
> one error found
>
>
> Now looking into case classes, I've only seen case classes derive from a
> non-case abstract class, such as the examples with Expr, Val, BinOp, etc.
>
> How would one write Point and ColoredPoint with case classes?

You can't at the moment. Currently case classes are prohibited from
extending other case classes (though they can both extend and be
extended by non-case classes).

I believe this isn't a semantic requirement so much as a limitation of
the current implementation (but that making an efficient
implementation with case classes extending eachother may be hard)

Reply | Threaded
Open this post in threaded view
|

Re: Case classes and equals

Erik Engbrecht
In reply to this post by Blair Zajac-3
Here's how I would do it, but it might not be what you're looking for:
 
trait Point {
  val x: Int
  val y: Int
}
 
object Point {
   private case class BasicPoint(val x: Int, val y: Int) extends Point
   def apply(x: Int, y: Int): Point = BasicPoint(x, y)
}
 
case class ColoredPoint(val x: Int, val y: Int, val color: Color.Value) extends Point

 
On 1/11/08, Blair Zajac <[hidden email]> wrote:
I was reading the Scala book and the chapter on object equality got into the
hairy details of writing a proper hashCode() and equals() method.  The book then
stated that using case classes removes the need to do all this work.

However, the following code does not compile:

case class Point(val x: Int, val y: Int)

object Color extends Enumeration {
  val red, green, blue = Value
}

case class ColoredPoint(override val x: Int,
                        override val y: Int,
                        val color: Color.Value)
  extends Point(x, y)


test.scala:7: error: implementation restriction: case class ColoredPoint and
case class Point cannot be combined in one object
case class ColoredPoint(override val x: Int,
           ^
one error found


Now looking into case classes, I've only seen case classes derive from a
non-case abstract class, such as the examples with Expr, Val, BinOp, etc.

How would one write Point and ColoredPoint with case classes?

Regards,
Blair




--
http://erikengbrecht.blogspot.com/
Reply | Threaded
Open this post in threaded view
|

Re: Case classes and equals

csar


On Jan 11, 2008 9:42 PM, Erik Engbrecht <[hidden email]> wrote:
Here's how I would do it, but it might not be what you're looking for:
 
trait Point {
  val x: Int
  val y: Int
}
 
object Point {
   private case class BasicPoint(val x: Int, val y: Int) extends Point
   def apply(x: Int, y: Int): Point = BasicPoint(x, y)
}
 
case class ColoredPoint(val x: Int, val y: Int, val color: Color.Value) extends Point

Why the twist with the private case class, shouldn't a non case class Point with a companion object do the trick?
 

 
On 1/11/08, Blair Zajac <[hidden email]> wrote:
I was reading the Scala book and the chapter on object equality got into the
hairy details of writing a proper hashCode() and equals() method.  The book then
stated that using case classes removes the need to do all this work.

However, the following code does not compile:

case class Point(val x: Int, val y: Int)

object Color extends Enumeration {
  val red, green, blue = Value
}

case class ColoredPoint(override val x: Int,
                        override val y: Int,
                        val color: Color.Value)
  extends Point(x, y)


test.scala:7: error: implementation restriction: case class ColoredPoint and
case class Point cannot be combined in one object
case class ColoredPoint(override val x: Int,
           ^
one error found


Now looking into case classes, I've only seen case classes derive from a
non-case abstract class, such as the examples with Expr, Val, BinOp, etc.

How would one write Point and ColoredPoint with case classes?

Regards,
Blair




--
http://erikengbrecht.blogspot.com/


Reply | Threaded
Open this post in threaded view
|

Re: Case classes and equals

Jamie Webb-2
On 2008-01-12 02:41:07 Carsten Saager wrote:

> On Jan 11, 2008 9:42 PM, Erik Engbrecht <[hidden email]>
> wrote:
>
> > Here's how I would do it, but it might not be what you're looking
> > for:
> >
> > trait Point {
> >   val x: Int
> >   val y: Int
> > }
> >
> > object Point {
> >    private case class BasicPoint(val x: Int, val y: Int) extends
> > Point def apply(x: Int, y: Int): Point = BasicPoint(x, y)
> > }
> >
> > case class ColoredPoint(val x: Int, val y: Int, val color:
> > Color.Value) extends Point
> >
>
> Why the twist with the private case class, shouldn't a non case class
> Point with a companion object do the trick?

No, because then equals and hashCode would not be automatically
provided, which was the point of this thread.

/J

Reply | Threaded
Open this post in threaded view
|

Re: Case classes and equals

Martin Odersky
I can confirm: Case classes inheriting from other case classes are
planned but we have not implemented it yet. Also not yet implemented
is the sort of equality method described in the book. But you can
expect it to be done once the final version is out ;-)

 -- Martin


On Jan 12, 2008 2:51 AM, Jamie Webb <[hidden email]> wrote:

> On 2008-01-12 02:41:07 Carsten Saager wrote:
> > On Jan 11, 2008 9:42 PM, Erik Engbrecht <[hidden email]>
> > wrote:
> >
> > > Here's how I would do it, but it might not be what you're looking
> > > for:
> > >
> > > trait Point {
> > >   val x: Int
> > >   val y: Int
> > > }
> > >
> > > object Point {
> > >    private case class BasicPoint(val x: Int, val y: Int) extends
> > > Point def apply(x: Int, y: Int): Point = BasicPoint(x, y)
> > > }
> > >
> > > case class ColoredPoint(val x: Int, val y: Int, val color:
> > > Color.Value) extends Point
> > >
> >
> > Why the twist with the private case class, shouldn't a non case class
> > Point with a companion object do the trick?
>
> No, because then equals and hashCode would not be automatically
> provided, which was the point of this thread.
>
> /J
>