Разве аргумент не соразмерный? - программирование
Подтвердить что ты не робот

Разве аргумент не соразмерный?

Я понимаю термины co-дисперсия и противоречие. Но есть одна маленькая вещь, которую я не могу понять. В курсе "Функциональное программирование в Scala" на coursera Мартин Ордерский упоминает, что:

Функции контравариантны в своих типах аргументов и ко-вариантах в их возвращаемые типы

Итак, например, в Java, пусть Dog extends Animal. И пусть функция будет:

void getSomething(Animal a){

и я вызываю вызов функции как

Dog d = new Dog();
getSomething(d)

Итак, в основном, что происходит, это Animal a = d. И в соответствии с wiki ковариация - это "Преобразование шире к узкому". И выше мы переходим от собаки к животному. SO не является аргументом типа ковариантным, а не контравариантным?

4b9b3361

Ответ 1

Это как функции определены в Scala:

trait Function1 [-T1, +R]  extends AnyRef

На английском языке параметр T1 является контравариантным, а тип результата R является ковариантным. Что это значит?

Если какой-либо фрагмент кода требует функции типа Dog => Animal, вы можете предоставить функцию типа Animal => Animal, благодаря контравариантности параметра (вы можете использовать более широкий тип).

Также вы можете предоставить функцию типа Dog => Dog, благодаря ковариации типа результата (вы можете использовать более узкий тип).

Это действительно имеет смысл: кто-то хочет, чтобы функция превращала собаку в любого животного. Вы можете предоставить функцию, которая преобразует любое животное (включая собак). Также ваша функция может возвращать только собак, но собаки все еще являются животными.

Ответ 2

Преобразование Dog в Animal преобразует узкие в более широкие, поэтому это не ковариация.

Ответ 3

Я помню, что меня смутило то самое предложение, когда я читал книгу Scala в 2007 году. Мартин поставляет ее так, как будто он говорит о языковой функции, но в этом предложении он только утверждает факт о функциях вообще, Scala, в частности, моделирует этот факт просто по регулярному признаку. Поскольку Scala имеет дисперсию объявления-сайта, выражение семантики является естественным для языка.

Java Generics, с другой стороны, поддерживает только разницу в использовании сайта, поэтому ближайшая к co/contravariance типа функции в Java заключается в том, чтобы вручную ее кодировать на каждом используемом сайте:

public int secondOrderFunction(Function<? super Integer, ? extends Number> fn) {
     ....
}

(предполагая, что для типа параметра и R для типа возвращаемого значения соответственно объявлен интерфейс Function<P, R>, P). Естественно, поскольку этот код находится в руках клиента и вообще не относится к функциям, утверждение о дисперсии типа типа/возвращаемого типа не применимо к какой-либо языковой функции Java. Он применим только в более широком смысле, относящемся к характеру функций.

В Java 8 появятся закрытие, что подразумевает первоклассные функции, но, как следует из комментария Jörg ниже, реализация не будет включать полноценный тип функции.