Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala / Dotty - Mix a trait into an EXISTING object

Is there a way to mix a trait into an existing object in either Dotty or Scala?

class SomeClass
trait SomeTrait

// This works, but it's not what I'm looking for:
new SomeClass with SomeTrait

// This is what I'm looking for, but it breaks:
val someClass = new SomeClass
someClass with SomeTrait

This answer provides a macro solution, but it's 7 years old, and I'm hoping (fingers crossed!) for something simpler.

like image 411
xyz2006tor Avatar asked Jan 01 '23 04:01

xyz2006tor


1 Answers

What about using typeclasses instead?

From the example you provided in the comment to your question:

trait Organism
trait Winged[O <: Organism]
trait Legged[O <: Organism]

class Dog extends Organism
object Dog {
   implicit val legged: Legged[Dog] = new Legged[Dog] { ... }
}

class Fly extends Organism
object Fly {
   implicit val winged: Winged[Fly] = new Winged[Fly] { ... }
   implicit val legged: Legged[Fly] = new Legged[Fly] { ... }
}

This is a very flexible approach that allows you to either define the Legged and Winged properties when designing a particular organism, or add them later through implicits outside the respective companion objects. You can force an organism to always have legs/wings by providing the implicit in the companion object, or leave that up to users of your code.

You can then define

// Only Winged organisms (ie. `O` for which `Winged[O]` is available implicitly
def makeItFly[O <: Organism : Winged](o: O) 
like image 142
francoisr Avatar answered Jan 08 '23 07:01

francoisr