Scala: Как составить требования к типовым параметрам универсальных классов? - PullRequest
3 голосов
/ 02 декабря 2010

Я создаю несколько параметризованных классов C [T] и хочу сделать некоторые требования к характеристикам типа T, чтобы иметь возможность быть параметром моего класса. Было бы просто, если бы я просто хотел сказать, что T унаследован от черт или классов (как мы делаем с упорядочением). Но я хочу, чтобы он также реализовал некоторые функции.

Например, я видел, что многие предопределенные типы реализуют MinValue и MaxValue, я хотел бы, чтобы мой тип T также реализовал их. Я получил несколько советов, чтобы просто определить неявную функцию. Но мне бы не хотелось, чтобы все пользователи были обязаны реализовать эту функцию для них, когда она уже реализована. Я мог бы реализовать их и в своем коде, но, похоже, это плохое быстрое решение.

Например, при определении куч, я хотел бы позволить пользователям создавать пустую кучу. В этих случаях я хочу инициализировать значение с минимальным значением, которое может иметь тип T. Очевидно, этот код не работает.

class Heap[T](val value:T,val heaps:List[Heap[T]]){
    def this()=this(T.MinValue,List())
}

Я также хотел бы получить несколько советов по поводу действительно хороших онлайн-ссылок на Scala 2.8.

Ответы [ 2 ]

5 голосов
/ 02 декабря 2010

Куча вещей, все они слабо связаны благодаря совместному использованию нескольких методов (хотя и с разными типами возвращаемых данных).Для меня это звучит как специальный полиморфизм!

бросить на класс типа ...

class HasMinMax[T] {
  def maxValue: T
  def minValue: T
}

implicit object IntHasMinMax extends HasMinMax[Int] {
  def maxValue = Int.MaxValue
  def minValue = Int.MinValue
}

implicit object DoubleHasMinMax extends HasMinMax[Double] {
  def maxValue = Double.MaxValue
  def minValue = Double.MinValue
}

// etc

class C[T : HasMinMax](param : T) {
  val bounds = implicitly[HasMinMax[T]]
  // now use bounds.minValue or bounds.minValue as required
}

ОБНОВЛЕНИЕ

[T : HasMinMax]нотация является контекстно-связанной и является синтаксическим сахаром для:

class C[T](param : T)(implicit bounds: HasMinMax[T]) {
  // now use bounds.minValue or bounds.minValue as required
}
2 голосов
/ 02 декабря 2010

Вы можете использовать границы типа:

trait Base

class C[T <: Base]

позволяет параметризовать C любым типом T, который является подтипом Base.

Или вы можете использовать неявные параметры для выражения требований:

trait Requirement[T] {
  def requiredFunctionExample(t: T): T
}

class C[T](implicit req: Requirement[T])

Таким образом, объекты класса C могут быть построены, только если существует реализация признака Requirement для типа T, с которым вы хотите параметризовать их. Вы можете разместить реализации Requirement для различных типов T, например, в объекте пакета, таким образом, перенося их в область действия всякий раз, когда импортируется соответствующий пакет.

...