Better classing through Scala
Sunday, 16 March 2008
Rather than the promised follow-up to my last post (it's coming, honest), I'm just going to update the way that I did the first section of that post. I realised earlier that rather than making my hastily-constructed RichIterable
a class, I should have made it a trait. In this way, other classes can use its functionality explicitly if they know about it and, critically, can override the functionality in a way that makes more sense to them.
To do this and still be able to do the implicit cast thing I showed, we also need a concrete class to mix the trait in with. Since you can't (as far as I know) mix in traits after you've created an object, if we just create a wrapper class for Iterable
objects:
class IterableWrapper[A]( underlying: Iterable[A] ) extends Iterable[A] { override def elements = underlying.elements }
Which means we can now express the implicit function from before as so, creating a new wrapper with our trait mixed in:
implicit def iterable2RichIterable[A]( iterable: Iterable[A]) = { new IterableWrapper( iterable ) with RichIterable[A] }
This means that any other collection can just extend the RichIterable
trait if they don't want to require the type conversion to use the new methods, or if they want to replace the functions with better implementations. Our actual RichIterable
trait can be a subtrait of Iterable
, too, meaning less indirection. It's wonderful I tells ya.
The extra curly brackets here do absolutely nothing; I just feel it's clearer to add them in if an expression like this one is too long to fit on a line.
Labels: programming, scala
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home