Reputation: 5494
I am using a library that has a sealed trait. I really need to extend this trait.
Is there a way (even a dirty one) to bypass that?
For a bit of background, this is what I am trying to work around : https://github.com/ReactiveMongo/ReactiveMongo/issues/247
Upvotes: 2
Views: 1925
Reputation: 12133
Don't extend, include, If you need to consider another option.
// Foo.scala
sealed trait Foo
case class Foo1(n: Int) extends Foo
case class Foo2(s: String) extends Foo
// Bar.scala
sealed trait Bar
case class BarFoo(foo: Foo) extends Bar
case class Bar3(b: Boolean) extends Bar
And the boilerplate can be reduced by implicit conversion
implicit def fooToBar(foo: Foo): Bar = BarFoo(foo)
Or if you want to add new methods to an existing class, use implicit classes:
// Foo.scala
sealed trait Foo
case class Foo1(n: Int) extends Foo
case class Foo2(s: String) extends Foo
// Quux.scala
// This class be called FooOps or FooExtra, if you like, name is irrelevant
implicit class Quux(foo: Foo) {
def quux: Boolean = foo match {
case Foo1(n) => n == 0
case Foo2(s) => s.isEmpty
}
}
Then you can use .quux
on Foo
values:
scala> Foo1(2).quux
res1: Boolean = false
scala> Foo2("").quux
res2: Boolean = true
This is about the same as extending, but with even less boilerplate, compare to:
case class Quux2(foo: Foo) {
def quux2: Boolean = foo match {
case Foo1(n) => n == 0
case Foo2(s) => s.isEmpty
}
}
implicit def fooToQuux2(foo: Foo): Quux2 = Quux2(foo)
scala> Foo1(2).quux
res0: Boolean = false
scala> Foo2("").quux
res1: Boolean = true
Upvotes: 5