Здравствуйте, Evgeny.Panasyuk, Вы писали:
G>>В вашем случае, важна именно полноценная монада maybe. Паллиатив вида variant[T, void] — не даст вам возможности поймать "go wrong".
G>>И важен тут, не столько Nothing (который, вполне может быть заменен и на void),
G>>сколько Just. Т.е. если за-предикатное выражение вычисляется в T, то "нормальный" результат вычисления if-без-else будет Just[T], а не T.
EP>Да, и я не вижу в этом проблемы.
А как вы собираетесь это потом использовать?! Повторюсь, смысл вычисления в maybe — возможность понять что "что-то пошло не так". Использование неявного приведения Just[T] к T (которое, кстати, вполне возможно) лишает нас этой возможности. Если нет неявного приведения, то "просто так" использовать результат вычисления if-без-else в тех же местах, где мы можем использовать результат вычисления if-с-else не получится.
Вот и вся проблема.
G>>Если теперь сравнить это с if-с-else, то видно следующее. Чтобы "в качестве результата можно использовать один тип результата" — в вашем случае — его придется вычислять в Just[T], а не в T. Что, вообще говоря, смысла лишено.
EP>Почему же? Для обобщённого кода как раз и не лишено — вне зависимости от того, значения каких типов возвращают ветки if-else, всё выражение вычислится в Variant.
Ну причем тут variant-то?! Речь идет о том, что нет смысла вычислять if-с-else в maybe.
EP>Для обычного, не обобщённого кода, да немного неудобно, но это обходится всего одним унарным оператором/унарной функцией, причём без потери производительности (Variant<T> всегда содержит внутри T, безусловно).
EP>Тут главное не забывать, что if-с-else в общем случае возвращает Variant<T, U>, а не просто Variant<T>, который является всего лишь частным случаем.
Уф. Если уж на то пошло, то обобщенный код — песня отдельная. Там можно и нормальный match использовать.
G>>Даже если "обернуть" все это в variant — это мало что изменит . Типы A и Some[A] — это таки разные типы.
G>>Можно потытаться "стереть границы" введя функторы, например... и вот тогда про "два синтаксиса" вообще никто вспоминать уж точно не будет
EP>В случае когда у нас Variant<T>, полноценный функторный fmap не нужен, точнее можно без него. Достаточно T unbox(Variant<T> x);, или короткого оператора.
По-ходу, как-то я не ясно выразился. Я вам про одно — вычисление if-без-else в maybe, а вы мне про другое — вычисление if-c-else в variant
Ладно, поговорим за variant...
А зачем вам какой-то явный unbox для variant? Вполне можно обойтись и неявным приведением к. Но, дело-то не в этом.
Смотрите... вот получили мы какой-то variant[string, int, ?DateTime], условно. Пусть даже у него есть какой-то unbox. Нормально обработать его можно только через PM. Вы же, надеюсь, не собираетесь прогонять его через очередной if?
Об этом и речь.
G>>Вычисление if-с-else в variant, само по себе (без попытки добиться "симметрии") может иметь смысл. Но только в том случае, когда PM и использование variant уйдут на ступень выше, так сказать.
EP>То есть основная проблема заключается в каких-то пробелах в Nemerle с Varaint'ом как таковым, а не в самой идеи if-else -> Variant?
Nemerle тут вообще не причем
Недостаточно вычислить if в variant[A, B, C]. Нужно еще как-то "узнать", что конкретно этот variant сейчас в себе несет... A, B или C. Даже в варианте с явным unbox, его тип вам заранее не известен. И его нужно будет либо дополнительно проверять... либо двойную диспетчеризацию городить... либо я ещё не знаю что
Но просто так (без PM) использовать не получится. Хоть в Nemerle, хоть еще где.
---
С уважением, Константин Сиваков