Система типов
От: _NN_ www.nemerleweb.com
Дата: 02.12.14 11:25
Оценка:
Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?

Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.

class A 
{
 virtual Nullable<int> X { get { return null; } } 
}
class B : A 
{
 override int X { get { return 1; } } 
}


Ну и далее в общем случае имея скажем List<U> определить в наследнике U или явно пустой список.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Система типов
От: dimgel Россия https://github.com/dimgel
Дата: 02.12.14 11:33
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?


_NN>Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.


В скале есть весьма узкоприменимый marker trait NotNull:

scala> class C1
defined class C1

scala> class C2 extends C1 with NotNull
defined class C2

scala> val c1: C1 = null
c: C1 = null

scala> val c2: C2 = null
<console>:9: error: type mismatch;
 found   : Null(null)
 required: C2
       val c2: C2 = null
             
scala> val c2: C2 = c1
<console>:10: error: type mismatch;
 found   : C1
 required: C2
       val c2: C2 = c1                                                                                                                                                                                             
                    ^                                                                                                                                                                                                    ^


Узкоприменимость его заключается в следующем... упс, пофиксили оказывается давно уже!

scala> def f(s: String with NotNull) {}
f: (s: String with NotNull)Unit

scala> f("hello")

scala> f(null)
<console>:9: error: type mismatch;
 found   : Null(null)
 required: String with NotNull
              f(null)
                ^


Раньше на строковый литерал ругалось, что мол null это.

_NN>Ну и далее в общем случае имея скажем List<U> определить в наследнике U или явно пустой список.


Можно что-нибудь через implicit conversion замутить наверное. С ходу впрочем не нарисую: я с implicits не настолько дружу.
Отредактировано 02.12.2014 11:44 dimgel . Предыдущая версия .
Re: Система типов
От: Jack128  
Дата: 02.12.14 12:44
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?


_NN>Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.


_NN>
_NN>class A 
_NN>{
_NN> virtual Nullable<int> X { get { return null; } } 
_NN>}
_NN>class B : A 
_NN>{
_NN> override int X { get { return 1; } } 
_NN>}
_NN>


_NN>Ну и далее в общем случае имея скажем List<U> определить в наследнике U или явно пустой список.


В общем случае, например С++:

#include <iostream>
using namespace std;


struct Base {
public:
    virtual ~Base(){}
    
    virtual Base* Clone() { return new Base(*this); }
};

struct Child: Base {
public:
    virtual Child*  Clone() override { return new Child(*this); }
};

int main() {
    // your code goes here
    return 0;
}
Re[2]: Система типов
От: _NN_ www.nemerleweb.com
Дата: 02.12.14 13:24
Оценка:
Здравствуйте, Jack128, Вы писали:

Это конечно хорошо, но вот vector<int> не является предком int .
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Система типов
От: Jack128  
Дата: 02.12.14 13:55
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Jack128, Вы писали:


_NN>Это конечно хорошо, но вот vector<int> не является предком int .

не является. А как ты хочешь?? чтоб любой тип можно было заменять любым другим ? Нужно же как то сказать компилятору, что экземпляр типа Base можно заменить экземплятором типа Child. В ООЯ для этого используют наследование.
Отредактировано 02.12.2014 14:04 Jack128 . Предыдущая версия .
Re: Система типов
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 02.12.14 14:53
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?

_NN>Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.

Так не будет же условиям базового удовлетворять, LSP нарушается. Мы же должны мочь скастить наследника в базовый, и там функция должна возвращать Nullable<int>, а не int.
Re[2]: Система типов
От: _NN_ www.nemerleweb.com
Дата: 02.12.14 16:07
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Здравствуйте, _NN_, Вы писали:


_NN>>Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?

_NN>>Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.

DM>Так не будет же условиям базового удовлетворять, LSP нарушается. Мы же должны мочь скастить наследника в базовый, и там функция должна возвращать Nullable<int>, а не int.


Согласен.
Поэтому и вопрос.

В теории можно было бы указать как создавать Nullable<int> из int и как получить int из Nullable<int> и на базе этого выводить полиморфизм .
int -> Nullable<int> нет проблем привести.
А Nullable<int> -> int может быть только в случае когда значение не null, т.е. усиление условия как и ковариантность.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Система типов
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.14 08:52
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?


_NN>Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.


_NN>
_NN>class A 
_NN>{
_NN> virtual Nullable<int> X { get { return null; } } 
_NN>}
_NN>class B : A 
_NN>{
_NN> override int X { get { return 1; } } 
_NN>}
_NN>

Ну, то есть мы хотим некий специальный вид ковариантности, когда у нас есть однозначное отображение X -> Y, но не обязательно Y->X.
Скажем, по любому X можно породить List<X> из одного элемента.
Или, скажем, по любому int можно получить double.
Т.е. наследник потенциально может усиливать ограничения на возврат значений, или вообще возвращать что угодно, если для этого чего угодно определена безопасная операция конверсии в тип, обещанный предком.
Принципиальных проблем не вижу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Система типов
От: _NN_ www.nemerleweb.com
Дата: 03.12.14 15:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ну, то есть мы хотим некий специальный вид ковариантности, когда у нас есть однозначное отображение X -> Y, но не обязательно Y->X.

S>Скажем, по любому X можно породить List<X> из одного элемента.
S>Или, скажем, по любому int можно получить double.
S>Т.е. наследник потенциально может усиливать ограничения на возврат значений, или вообще возвращать что угодно, если для этого чего угодно определена безопасная операция конверсии в тип, обещанный предком.
S>Принципиальных проблем не вижу.

Именно так.
Есть ли такое в природе ?
Хотя теория для этого ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Система типов
От: jazzer Россия Skype: enerjazzer
Дата: 03.12.14 18:36
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?


А при чем тут система типов? Это правила ковариантности методов просто, они любые могут быть же. Скажем, в С++ и тому подобных правило формулируется в терминах (открытого) наследования, но можно и более сложные правила предусмотреть, скажем, через какой-то специальный type traits.
Тут главная фишка в том, что в том же С++ наследование автоматом обеспечивает бинарную совместимость объектов, поэтому можно возвращать наследников и не париться — а для других пар типов бинарная совместимость не гарантируется. Но это в С++, в других языках могут передаваться просто словари и в этом смысле все объекты совместимы постольку, поскольку словари содержат необходимые члены, и, соответственно, в таких языках нет проблем сделать то, что ты хочешь.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Система типов
От: Кодт Россия  
Дата: 09.12.14 17:11
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Есть ли система типов, которая позволяет переопределить M<U> как U в наследнике ?


_NN>Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.


Не "например", а именно Nullable, я так полагаю.
Если ты ограничился (очаровался) дотнетовской системой типов, в которой Nullable — это дженерик поверх int.
Там это сделано от безысходности, потому что иначе нельзя.

Лучше сказать, что есть Nullable<int> и Valid<int>. Между ними можно наладить какие-то родственные связи.
На чтение и на запись они друг друга по-разному заменяют.

Т.е. у нас получаются три слоя
— readable<T>, writable<T> (const и не-const — недостаточное приближение)
— T = valid<U>, nulled<U>, nullable<U>
— U = int

В С++ можно на шаблонах сделать ко/контра-вариантность вручную, но это, вероятно, будет страшненько.
А изкоробочную на наследовании — ещё более страшненько.

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

В принципе, можно в дизайн языка внести такие штуки, — как, например, в скале ко-контра-вариантность в параметрах дженериков указывают.
Вопрос лишь в том, в какой момент остановиться.

Ведь, например, список постоянного размера или дерево ограниченной глубины также соотносится со списком/деревом большего, меньшего и произвольного размера.

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

Но я что-то подозреваю, что на этих ограничениях можно построить машину Тьюринга и ввести компилятор в тотальное изумление.
Поэтому самое общее решение было бы — контракты и проверки. Вынесенные в рантайм.
Перекуём баги на фичи!
Re[2]: Система типов
От: _NN_ www.nemerleweb.com
Дата: 10.12.14 07:03
Оценка:
Здравствуйте, Кодт, Вы писали:

_NN>>Например имея Nullable<int> в базовом классе , наследник мог бы определить int , тем самым усиливая условия и удовлетворяя требованием базового.


К>Не "например", а именно Nullable, я так полагаю.

К>Если ты ограничился (очаровался) дотнетовской системой типов, в которой Nullable — это дженерик поверх int.
К>Там это сделано от безысходности, потому что иначе нельзя.
Как раз именно пример.
Сам тип не важен, может быть хоть double => int.

К>В С++ можно на шаблонах сделать ко/контра-вариантность вручную, но это, вероятно, будет страшненько.

К>А изкоробочную на наследовании — ещё более страшненько.
Вручную то можно , только придется все обернуть в шаблоны.

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


К>В принципе, можно в дизайн языка внести такие штуки, — как, например, в скале ко-контра-вариантность в параметрах дженериков указывают.

К>Вопрос лишь в том, в какой момент остановиться.
Я бы хотел возможность добавлять любой свой класс в эту вариантность.

К>Ведь, например, список постоянного размера или дерево ограниченной глубины также соотносится со списком/деревом большего, меньшего и произвольного размера.

Если кто-то считает это логичным, то может и добавить.
Например Tree<int> при глубине 1 может превратиться в int[] , а при глубине 1 и с одним элементом в просто int.

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

Ну да, что-то вроде Агды, только я там не знаю если такой финт возможен.
К>Фантомные типы скалы и хаскелла — из той же серии.
Спасибо, гляну.

К>Но я что-то подозреваю, что на этих ограничениях можно построить машину Тьюринга и ввести компилятор в тотальное изумление.

К>Поэтому самое общее решение было бы — контракты и проверки. Вынесенные в рантайм.
Это другая сторона проблемы.
Мы тут в философии =)
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.