- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Looking for clever tricks (possibly type voodoo) to minimize writing code. (Not really important, but kinda interesting).
Sun, 2011-05-22, 20:55
Here's some (probably illegal) code that sorta gets across what I want to do (and even if it's not illegal, I know that subclassing case classes is frowned on):
case class Borders[T](left: T, top: T, right: T, bottom: T)
case class BordersFloat(left: Float, top: Float, right: Float, bottom: Float) extends Borders[Float](left, top, right, bottom) { def multiplySides(m: Float) = this.copy(left = left*m, right=right*m)}
"Borders" are properties that have to do with the rectangle drawn around something; so Borders[Float] could give thickness of the sides, Borders[Color] could assign a different color to each side, etc.
So the most general form of this is Borders[T], as defined above. But then, if I have a class Borders[Float], I can define some nice numeric-related operations that wouldn't apply to say, Borders[LineStyle].
If I define this using traditional classes it's not too hard, as I can use subclassing and define the appropriate methods in the specialized classes, But I'd really like to use case classes so I can make use of the "copy" functionality; for Borders it doesn't matter so much, but some other of my classes will have quite a few more fields.
So just wondering if anyone can suggest clever tricks.
Thanks,Ken
case class Borders[T](left: T, top: T, right: T, bottom: T)
case class BordersFloat(left: Float, top: Float, right: Float, bottom: Float) extends Borders[Float](left, top, right, bottom) { def multiplySides(m: Float) = this.copy(left = left*m, right=right*m)}
"Borders" are properties that have to do with the rectangle drawn around something; so Borders[Float] could give thickness of the sides, Borders[Color] could assign a different color to each side, etc.
So the most general form of this is Borders[T], as defined above. But then, if I have a class Borders[Float], I can define some nice numeric-related operations that wouldn't apply to say, Borders[LineStyle].
If I define this using traditional classes it's not too hard, as I can use subclassing and define the appropriate methods in the specialized classes, But I'd really like to use case classes so I can make use of the "copy" functionality; for Borders it doesn't matter so much, but some other of my classes will have quite a few more fields.
So just wondering if anyone can suggest clever tricks.
Thanks,Ken
Sun, 2011-05-22, 21:37
#2
Re: Looking for clever tricks (possibly type voodoo) to minimiz
Oh, cool. I don't understand it yet, but I've come across references to Numeric before, and now I finally have an excuse to learn about it. Plus I get to learn more about implicits, which I have used hardly at all.
Thanks!Ken
Thanks!Ken
On Sun, May 22, 2011 at 12:55 PM, Ken McDonald wrote:
> Here's some (probably illegal) code that sorta gets across what I want to do
> (and even if it's not illegal, I know that subclassing case classes is
> frowned on):
> case class Borders[T](left: T, top: T, right: T, bottom: T)
> case class BordersFloat(left: Float, top: Float, right: Float, bottom:
> Float) extends Borders[Float](left, top, right, bottom) {
> def multiplySides(m: Float) = this.copy(left = left*m, right=right*m)
> }
> "Borders" are properties that have to do with the rectangle drawn around
> something; so Borders[Float] could give thickness of the sides,
> Borders[Color] could assign a different color to each side, etc.
> So the most general form of this is Borders[T], as defined above. But then,
> if I have a class Borders[Float], I can define some nice numeric-related
> operations that wouldn't apply to say, Borders[LineStyle].
> If I define this using traditional classes it's not too hard, as I can use
> subclassing and define the appropriate methods in the specialized classes,
> But I'd really like to use case classes so I can make use of the "copy"
> functionality; for Borders it doesn't matter so much, but some other of my
> classes will have quite a few more fields.
> So just wondering if anyone can suggest clever tricks.
Use type classes:
// you can specialize if you want to.
case class Borders[T](left: T, top: T, right: T, bottom: T) {
def multiplySides(m: T)(implicit numeric: Numeric[T]) = {
import numeric._
copy(left=m*left,right=m*right)
}
}
Borders(1,2,3,4).multiplySides(5) // ok, gives Borders(5,2,15,4)
Borders("1","3","4","5").multiplySides("4")
:10: error: could not find implicit value for parameter
numeric: Numeric[java.lang.String]
Borders("1","3","4","5").multiplySides("4")