deltanovember
deltanovember

Reputation: 44061

In Scala, is there a way to "pass through" traits to variables within a class?

Suppose I have a trait NYSE that can retrieve the market currency

trait NYSE extends Market {
  override def getCurrency = "USD"
}

Now suppose I have a Trader class that needs to know the currency. Easy:

val trader = new Trader with NYSE

However suppose within Trader I have something like

val Database = new Database

But I really want to pass market information so that

val trader = new Trader with NYSE

Automatically initialises the internal variable as follows

val Database = new Database with NYSE

Similarly

val trader = new Trader with LSE

Automatically does

val Database = new Database with LSE

Is there a way to achieve this?

Upvotes: 1

Views: 1264

Answers (2)

paradigmatic
paradigmatic

Reputation: 40461

I think type classes are perfect for what you are looking for:

trait Currency[T] { def get: String }
trait DatabaseProvider[T] { def get: String }

object Markets {

  trait NYSE

  implicit case object NYSECurrency extends Currency[NYSE] {
    def get = "USD"
  }
  implicit case object NYSEDBProvider extends DatabaseProvider[NYSE] {
    def get = "NYSE_DB"
  }

}

class Trader[T]( 
  implicit val currency: Currency[T],
  val dbProvider: DatabaseProvider[T]
) {
  def getCurrency = currency.get
  def getDatabase = dbProvider.get
}

object Demo extends App {
  import Markets._
  val trader = new Trader[NYSE]
  println( trader.getCurrency )
  println( trader.getDatabase )
}

You can add as many markets you want and you uncouple completely the different implementations.

Upvotes: 5

Rex Kerr
Rex Kerr

Reputation: 167901

Can you just

trait DatabaseProvider { def getDatabase: Database }

class Trader extends DatabaseProvider {
  val Database = getDatabase
  ...
}

trait NYSE extends Market with DatabaseProvider {
  override def getCurrency = "USD"
  def getDatabase = new Database with NYSE
}

Upvotes: 2

Related Questions