Как я могу получить доступ к объекту-компаньону класса Scala, переданного как параметр типа? - PullRequest
0 голосов
/ 30 мая 2018

У меня есть класс дел с сопутствующим объектом:

object Taco extends Dinner[Taco] {
  def ingredientNames: Seq[String] = Seq("filling", "cheese", "sauce")
}

case class Taco(filling: Meat, cheese: Cheese, sauce: Sauce) 
extends Dinner

И еще один:

object Cheeseburger extends Dinner[Cheeseburger] {
  def ingredientNames: Seq[String] = Seq("cheese", "bun", "condiments")
}

case class CheeseBurger(cheese: Cheese, bun: Bun, condiments: Seq[Condiment]) 
extends Dinner[Cheeseburger]

Мне нужно получить названия ингредиентов для этих ужинов перед тем, как создавать экземпляры ужина:

def printMenu[D <: Dinner[D]]: String = ???

Как получить доступ к сопутствующему объекту подкласса Dinner?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Типы классов на помощь:

trait Dinner { ... }
trait DinnerCompanion[A <: Dinner] {
  implicit def self: DinnerCompanion[A] = this
  def ingredientNames: Seq[String]
  ...
}

object Taco extends DinnerCompanion[Taco] {
  def ingredientNames: Seq[String] = Seq("filling", "cheese", "sauce")
}

case class Taco(filling: Meat, cheese: Cheese, sauce: Sauce) extends Dinner

def printMenu[A <: Dinner](implicit companion: DinnerCompanion[A]): String = 
  companion.ingredientNames.mkString(", ")
0 голосов
/ 31 мая 2018

Возможно, вам нужна следующая конструкция (вдохновленная GenericCompanion из стандартной библиотеки коллекций):

type Condiment = String
type Meat = String
type Cheese = String
type Sauce = String
type Bun = String


trait Dinner[A] {
  def companion: DinnerCompanion[A]
}

trait DinnerCompanion[A] {
  def ingredientNames: Seq[String]
}

case class Taco(filling: Meat, cheese: Cheese, sauce: Sauce) 
extends Dinner[Taco] {
  def companion = Taco
}

implicit object Taco extends DinnerCompanion[Taco] {
  def ingredientNames: Seq[String] = Seq("filling", "cheese", "sauce")
}

case class CheeseBurger(cheese: Cheese, bun: Bun, condiments: Seq[Condiment]) 
extends Dinner[CheeseBurger] {
  def companion = CheeseBurger
}

implicit object CheeseBurger extends DinnerCompanion[CheeseBurger] {
  def ingredientNames: Seq[String] = Seq("cheese", "bun", "condiments")
}

def printMenu[D: DinnerCompanion]: String = 
  implicitly[DinnerCompanion[D]].ingredientNames.mkString

Теперь у каждого экземпляра Dinner есть метод companion и companionв свою очередь имеет ingredientNames.

EDIT добавлено printMenu (не имеет никакого отношения к объектам-компаньонам, использует object Taco и object CheeseBurger в качестве обычных экземпляров класса типов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...