Генерализация Option
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 22.11.16 21:41
Оценка:
В очередной раз тут понадобился упрощенный аналог tagged union, т.е. некий тип, представляющий собой объединение набора предопределенных типов по "или" (а не по "и", как в кортежах), и подумалось — может слегка обобщить Option до 7-8 type аргументов? Текущий тогда придется переобозвать как нибудь типа NullableOption. Ну и подумать на тему вариантов с неким общим для всех типов TCommonData и без такового.
Кто что думает?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re: Генерализация Option
От: Sinix  
Дата: 23.11.16 13:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>В очередной раз тут понадобился упрощенный аналог tagged union, т.е. некий тип, представляющий собой объединение набора предопределенных типов по "или" (а не по "и", как в кортежах), и подумалось — может слегка обобщить Option до 7-8 type аргументов? Текущий тогда придется переобозвать как нибудь типа NullableOption. Ну и подумать на тему вариантов с неким общим для всех типов TCommonData и без такового.

AVK>Кто что думает?

А как оно с седьмым шарпом дружить-то будет?

operator is вроде в релиз не попадает, если ограничиться седьмым шарпом, то получается бессмысленный и беспощадный изврат в духе
    struct Is<T1, T2>
    {
        public static implicit operator T1(Is<T1,T2> t)
        {
            return t._1;
        }

        public static implicit operator T2(Is<T1, T2> t)
        {
            return t._2;
        }

        private T1 _1;
        private T2 _2;

        public Is(T1 t)
        {
            _1 = t;
            _2 = default(T2);
        }

        public Is(T2 t)
        {
            _1 = default(T1);
            _2 = t;
        }
    }
...
    var temp = new Is<int, string>("hello");
    // ...
    int intVal = temp;
    Console.WriteLine(intVal); // 0;

— эт раз.

Даже если бы попал — ADT тоже будут только в C#8, соответственно предупреждений о неполном match не будет — эт два.

Остаётся только одно решение: метод Match(Action<T1> case1, Action<T2> case2), который можно закопать не выпуская, как по мне.
Тип, который для каждого использования требует аллокации делегата с замыканием, на хороший код точно не тянет.

Я бы вообще убрал заигрывания с функциональщиной до нормальной поддержки в шарпе. Для реальных задач есть F#, для хипстеров — langext, чего ещё надо-то?
Re[2]: Генерализация Option
От: Слава  
Дата: 23.11.16 13:22
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Я бы вообще убрал заигрывания с функциональщиной до нормальной поддержки в шарпе. Для реальных задач есть F#, для хипстеров — langext, чего ещё надо-то?


Я бы сказал, что langext нужен для ЧУДОВИЩНОГО торможения студии.
Re[2]: Генерализация Option
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.11.16 14:34
Оценка:
Здравствуйте, Sinix, Вы писали:

S>А как оно с седьмым шарпом дружить-то будет?


А что в седьмом шарпе такого, что он требует отдельного упоминания?

S>operator is вроде в релиз не попадает, если ограничиться седьмым шарпом, то получается бессмысленный и беспощадный изврат в духе


Ты словами раскрой, нафига такой изврат нужен. Я имел в виду примерно такую структуру, как сейчас в Option, только расширенную на несколько типов. Что то вроде https://github.com/mcintyre321/OneOf.

S>Даже если бы попал — ADT тоже будут только в C#8, соответственно предупреждений о неполном match не будет — эт два.


Да не надо никакого ПМ. Все намного проще — достаточно метода Match с набором делегатов для каждого типа. Эта штука как раз и нужна в случае, если ПМ по типам нет.

S>Остаётся только одно решение: метод Match(Action<T1> case1, Action<T2> case2), который можно закопать не выпуская, как по мне.


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

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


Аллокация делегата в большинстве случаев совершенно не проблема. Но я бы с удовольствием послушал насчет альтернатив.

S>Я бы вообще убрал заигрывания с функциональщиной до нормальной поддержки в шарпе. Для реальных задач есть F#, для хипстеров — langext, чего ещё надо-то?


Так задачу то мне как решать? Тянуть F# из-за пары-тройки мест в проекте? Или херачить классические визиторы, раздувающие мушиный код в слона?
ИМХО ты не совсем верно меня понял. Я не собираюсь пытаться эмулировать tagged unions в шарпе, тне нужно средство для хранения в одной сущности нескольких типов, причем часто у этих типов даже общих данных нет.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: Генерализация Option
От: Sinix  
Дата: 23.11.16 14:43
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>ИМХО ты не совсем верно меня понял.

Угу, есть такое дело. Не проще тогда готовый OneOf подтянуть / позаимствовать? Ты на него ссылку как раз давал.
Re[4]: Генерализация Option
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.11.16 14:54
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Угу, есть такое дело. Не проще тогда готовый OneOf подтянуть / позаимствовать? Ты на него ссылку как раз давал.


Не проще. Во-первых тянуть из-за одной мелочи отдельную либу не хочется, а во-вторых я пока не уверен в качестве реализации. Да и вообще, мы же этот вопрос в самом начале уже обсуждали — половину нашего функционала можно найти в другом месте, а ObjectPoll вообще цельнотянутый, да как бы не по твоему предложению.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: Генерализация Option
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.11.16 10:55
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Угу, есть такое дело. Не проще тогда готовый OneOf подтянуть / позаимствовать? Ты на него ссылку как раз давал.


В итоге остались вопрос — как его обозвать:
1) Положить отдельно под именем OneOf/ValueOneOf, для первого варианта с возможностью null оставить Option/ValueOption, для второго подойдет родной Nullable.
2) Обобщить вместе с Option. Тогда получится Option/NullableOption/ValueOption/NullableValueOption. Изменение ломающее, но не думаю что кто то текущий Option использует активно.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: Генерализация Option
От: Sinix  
Дата: 25.11.16 10:59
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>В итоге остались вопрос — как его обозвать:

Мне первый вариант нравится больше.
Re[4]: Генерализация Option
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.11.16 18:30
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Угу, есть такое дело. Не проще тогда готовый OneOf подтянуть / позаимствовать? Ты на него ссылку как раз давал.


Добавил. Заимствовать не стал, написал с нуля с существенными отличиями.
Есть один вопросик с реализацией хранения значения в ValueOneOf. Сейчас оно хранится в object и кастится при запросе. Это дает плюс по памяти, однако приводит к тормозам из-за кастинга и боксинга value-типов в type параметрах.
Альтернатива одна — заводить по полю на каждый тип. Но это приведет к росту расхода памяти, особенно в случае value типов.
Что выбрать — ХЗ.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.