Re[7]: [ANN] Scala 2.4.0: очередные изменения языка
От: palm mute  
Дата: 19.03.07 09:42
Оценка: 29 (2)
Здравствуйте, eao197, Вы писали:

Собственно, с этим все понятно и у меня никогда проблем с ковариантностью не было. А вот контравариантность -- она вроде как есть, даже в стандартной библиотеке Scala используется:
E>
E>abstract trait Function1 [-T1, +R] extends java.lang.Object with scala.ScalaObject
E>

E>но, блин, сходу вспомнить, что она означает и придумать какой-то пример ее использования -- не получается.

Что такое Function1, довольно просто объяснить.
Это, насколько я понял, функция с одним аргументом, запакованная в объект; в аннотации вариантности [-T1, +R] закодированы обычные правила подтипизации функций. Над ними нужно пару раз помедитировать, но на самом деле ничего сложного нет: тип функций a' -> b' будет подтипом a -> b тогда, когда b' является подтипом b и a является подтипом a'. Почему так? Допустим, мы передаем функцию как аргумент (псевдокод):
class Animal : Object {}
class Banana : Plant {}
class Apple : Plant {}
class Elephant : Animal {}

function foo(f : Plant->Animal)
{
  Animal animal = f(new Banana);
}

function ok(x : Fruit) : Elephant
{
...
   return new Elephant;
}

function bad1(x : Apple) : Animal
{
   ...   
}

function bad2(x : Plant) : Object
{
   ...   
}
...
foo(ok); // т.к. банан - тоже фрукт, ok умеет с ним работать.
         // т.к. слон - тоже животное, foo сможет обработать возвращенное значение
foo(bad1); // bad1 не справится с бананом, она умеет есть только яблоки
foo(bad2); // foo не поймет, что ей вернула функция bad2, 
           // она ожидала животное, а получила непонятный "объект"


Более формально об этом можно почитать в статьях Луки Карделли, например:
On understanding types, data abstraction, and polymorphism
Typeful programming.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.