Структурный тип Scala как параметр типа функции

Я хочу создать некоторую функцию "общего сумматора", которая будет работать для всех типов, которые поддерживают операцию "+". Я пробовал структурную типизацию как параметр типа функции, но это не компиляция:

def f[T <: { def +(x: T): T} ](a: T, b: T): T = a + b

error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement

Есть ли способ обойти эту проблему?

2 ответа

Я не думаю, что есть обходной путь для этой проблемы, за исключением, например, использования классов типов. Однако вам понадобятся неявные преобразования для типов, которые вы хотите обработать.

Спецификация языка Scala гласит:

В объявлении метода в структурном уточнении тип любого параметра значения может ссылаться только на параметры типа или абстрактные типы, которые содержатся внутри уточнения. То есть он должен ссылаться либо на параметр типа самого метода, либо на определение типа в уточнении. Это ограничение не распространяется на тип результата функции.

Вот почему вы получаете ошибку.

Пример реализации может выглядеть так

trait AddLike[T] {
  def +(x: T): T
}

def f[T <% AddLike[T]](a: T, b: T): T = a + b

implicit def num2AddLike[T](a: T)(implicit ev: Numeric[T]) = new AddLike[T] { def +(b: T) = ev.plus(a, b) }
implicit def str2AddLike(a: String) = new AddLike[String] { def +(b: String) = a + b }

f(1, 2)
f("one", "two")

Я не думаю, что в Scala есть способ создать экземпляр универсальной функции, который может автоматически обрабатывать все типы, которые могут быть добавлены. Однако в исходном коде Scala эта функция может быть написана _ + _, а в некоторых ситуациях типы будут выведены.

def triple[T](value: T)(add: (T, T) => T): T = add(add(value, value), value)

triple(10)(_ + _)
triple("w")(_ + _)

def tripler[T](add: (T, T) => T): T => T = (value: T) => triple(value)(add)

val tripleDouble: Double => Double = tripler(_ + _)
tripleDouble(3.2)

К сожалению, существует много таких ситуаций, когда вы хотите, чтобы типы выводились, а их не будет.

Другие вопросы по тегам