Re[4]: Еще вопрос.
От: WolfHound  
Дата: 19.05.18 15:16
Оценка:
Здравствуйте, hi_octane, Вы писали:

_>Если бы это всё были монады а не разные захардкоженные сущности, то с точки зрения монад это всё абсолютно одно и тоже, с единым способом работы со всеми этими штуками. Нет никаких причин (и даже способов) различать во что обёрнуты значения, главное что это Monad<Int>. И если бы это было и для языка одним и тем же за счёт годного синтаксического сахара, т.е. если бы все переменные были монадами, то Dictionary<void, int> — это естественным образом получался бы List.

Не получится. У словаря нет порядка. У списка есть.
Далее есть множество и мультимножество. Они оба нужны. Но вот такой вот параметризацией из словаря их не получишь.

Если уж говорить об обобщении коллекций нужно начинать с чего-то типа этого
https://www.boost.org/doc/libs/1_67_0/libs/multi_index/doc/index.html

_>И в случае списка ты автоматом получишь последовательное или параллельное (в зависимости от деталей реализации обёртки) выполнение, а может даже распределённое или на GPU, а не как сейчас — ошибку типизации.

Баловство это. Если нужно что-то распараллелить, то нужно брать вот эту штуку или что-то похожее.
http://halide-lang.org/

_>Там всё очень алгебраично (для тех кто этот мем пропустил см. под катом)

_>
  Скрытый текст
_>алгебраично

Неалгебраичный канал про математику.
https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw/videos?disable_polymer=1
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Монады
От: Evgeny.Panasyuk Россия  
Дата: 20.05.18 06:08
Оценка: +1
Здравствуйте, D. Mon, Вы писали:

DM>Чтобы писать красивый монадный код, который бы работал в разных априори неизвестных монадах, надо, во-первых, чтобы система типов позволяла абстрагироваться не только от типа Т, но и от контейнера (функтора) F<T>, т.е. нужны higher-kinded types. А их кроме хаскеля со скалой нигде нет практически, даже в расте нет.


Есть в C++, сам же знаешь

DM>А во-вторых нужна поддержка синтаксиса, та же do-нотация, этого тоже нигде особо нет. Так что монады как-то в другие языки не пошли.


При необходимости реализуется через макросы в C++
Автор: Evgeny.Panasyuk
Дата: 07.01.14
.
Re[3]: Монады
От: Evgeny.Panasyuk Россия  
Дата: 20.05.18 06:25
Оценка: 9 (1)
Здравствуйте, hi_octane, Вы писали:

_>Вот что в скале бесит (и наверное в хакселе, хоть я на нём и не пишу, но сорцы иногда читаю) — так это то что эта самая do-нотация нужна в явном виде. А в скале — так это запихнуто в for-comprehension, который спотыкается на простейших вещах (типа нормально иф в этот фор всунуть). Неужели нельзя добавить сахара в компилятор чтобы он распознавал код на монадах, и правильно его рассахаривал без do-нотации? Вроде задаче не сложнее чем та которую решает компилятор C# преобразуя функцию с async/await.


Альтернативой DO-нотации (то есть альтернативой нарезки кода на замыкания, пусть и автоматической) является call-with-current-continuation — среда выполнения в явном виде отдаёт нам всё необходимое для многократного продолжения с текущего места.
Это например позволяет оманадить код не меняя привычного синтаксиса. Вот конкретный пример
Автор: Evgeny.Panasyuk
Дата: 16.01.14
.
Re[5]: Монады
От: Evgeny.Panasyuk Россия  
Дата: 20.05.18 06:37
Оценка: +1
Здравствуйте, hi_octane, Вы писали:

_>В C# эту проблему решили чуть более естественно в async/await, но увы в CLR нет higher-order types, так что нет и монад.


Даже если были бы — await это всё равно не то, например монаду List на нём не выразить, так как нужна поддержка многократного запуска продолжения с одного места.
Re[3]: Монады
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 21.05.18 07:17
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

DM>>Чтобы писать красивый монадный код, который бы работал в разных априори неизвестных монадах, надо, во-первых, чтобы система типов позволяла абстрагироваться не только от типа Т, но и от контейнера (функтора) F<T>, т.е. нужны higher-kinded types. А их кроме хаскеля со скалой нигде нет практически, даже в расте нет.


EP>Есть в C++, сам же знаешь


Да, C++ и D тоже.

DM>>А во-вторых нужна поддержка синтаксиса, та же do-нотация, этого тоже нигде особо нет. Так что монады как-то в другие языки не пошли.


EP>При необходимости реализуется через макросы в C++
Автор: Evgeny.Panasyuk
Дата: 07.01.14
.


Ой, это ж ужас. В качестве упражнения еще сойдет, но на практике этим пользоваться невозможно.
Re[3]: Монады
От: Klapaucius  
Дата: 21.05.18 08:38
Оценка: 9 (1)
Здравствуйте, hi_octane, Вы писали:

_>Вот что в скале бесит (и наверное в хакселе, хоть я на нём и не пишу, но сорцы иногда читаю) — так это то что эта самая do-нотация нужна в явном виде. А в скале — так это запихнуто в for-comprehension, который спотыкается на простейших вещах (типа нормально иф в этот фор всунуть). Неужели нельзя добавить сахара в компилятор чтобы он распознавал код на монадах, и правильно его рассахаривал без do-нотации? Вроде задаче не сложнее чем та которую решает компилятор C# преобразуя функцию с async/await.


что-то такое (если я правильно понял) есть, но не в хаскеле
в idris
http://docs.idris-lang.org/en/latest/tutorial/interfaces.html#notation
в DDC
https://www.youtube.com/watch?v=wG8AErq6Bbo&amp;list=PLnqUlCo055hX1F0PCi9FjdllYQMwCQvps&amp;index=6
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[5]: Еще вопрос.
От: vdimas Россия  
Дата: 22.05.18 20:32
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Не получится. У словаря нет порядка. У списка есть.


У списка порядок подразумеваемый:
List<Value> === Dictionary<int, Value>
Доступ к элементам списка по индексу всё-равно ассоциативный.


WH>Далее есть множество и мультимножество. Они оба нужны.

WH>Но вот такой вот параметризацией из словаря их не получишь.

Dictionary<Key, List<Value>>
(если внутренее устройство не принципиально)


WH>Если уж говорить об обобщении коллекций нужно начинать с чего-то типа этого

WH>https://www.boost.org/doc/libs/1_67_0/libs/multi_index/doc/index.html

Это просто набор индексов над данными.
Вся фишка в хранении этих индексов — для не примитивных типов хранится не значение ключа, а ссылка на значение ключа в самих данных.
Но это опять тонкости реализации.
Re: Монады
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.06.18 16:39
Оценка: 28 (2) +1
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Начинаю тему и приглашаю в нее тех, кто лучше меня в этом разбирается

Я плохо разбираюсь, но попробую свои 5 копеек вставить.

Начнем с того, что монада — это "паттерн" в понимании большинства программистов. Это не конструкция языка, хотя некоторые языки имеют конструкции, облегчающие использование монад.

Паттерн опирается паттерн на полиморфизм. В языках без полиморфизма монады не але.
Паттерн состоит из ЧЕТЫРЕХ элементов:
1) Полиморфный тип M<T>, тип обычно монадой и называют
2) Функция конструктор (return) T->M<T>
3) Функция связывания (bind) (M<T>, T->M<V>) -> M<V>
return и bind не произвольные, а должны подчиняться правилам:
— bind(return x, f) = f x
— bind(x, return) = x
Правило "монадного нуля"

— bind(bind(m,f), g) = bind(m, x -> bind(f(x), g))
Правило "ассоциативности bind"


4) Этот элемент отличает монадного теоретика от монадного практика.
Для практического использования монады нужна функция (run) M<T> -> T
Возможно такая функция будет не одна.


MSS>Для каких именно практических нужд пригодны монады?


Практическая польза монад — иметь один набор более-менее понятных функций для работы с объектами разной природы.

1) flatten :: M<M<T>> -> M<T> = bind(m, x->x)
2) map :: (M<T>, T->V) -> M<V> = bind(m, x-> return f(x))
3) filter :: (M<T>, T-> Maybe<V>) -> M<V>. Увы, конкретная реализация зависит от M<T> и не всегда возможна.
4) merge :: (M<T>, M<V>) -> M<(T,V>) = bind(t, x -> bind(v, y -> return (x,y)))
5) join :: (M<T>, M<V>, (T,V) -> bool) -> M<(T,V>) = filter(merge(t,v), (x,y) -> if f(x,y) then Maybe(x,y) else None). Тоже от filter зависит.
итд (лень придумывать).

При наличии в языке полиморфизма второго порядка часть функций можно вынести в библиотеки.

Но самая главня фишка, которая уже должна броситься в глаза: везде на входе и выходе M<T>.
То есть код с монадой по большей части будет выглядеть так:
bind(bind(bind(x,f),g),h)


Ни проверок, ни try\catch в таком коде не нужно. Вся "грязь" перемещается в run.
Вся сложность "инкапсулируется" в функциях f,g,h, что очень в духе Функционального Программирования.

Программистам надо писать функции типа T->M<V> и не особо думать о композиции функций. За счет частичного применения T->M<V> может иметь любое количество агрументов перед T.
Это довольно сильное преимущество, если вместо абстрактного M<T> подставить List, Maybe, Try, Parser, Future, Writer и IO монады.

MSS>и что называется монадой в языках, отличных от Хаскеля?

В других языках монадой называется все то же самое.

Но, как уже заметили, код с кучей вложенных bind смотрится криво.
Поэтому в языках, где bind записывается инфиксно (x `bind` f) монады оказываются гораздо красивее.
В хаскеле это оператор >>=, в C# это query comprehension.


Также в хаскеле есть особенность — run функция для IO встроена в рантайм.


MSS>Получается старый добрый декоратор который можно реализовать в обычных ОО языках наследованием с перекрытием пабликов.

Можно и декоратором назвать, главное bind реализовать правильно.


Самый главный монадный закон

Об этом не пишут в книгах и статьях.
Монады появляются с появления функции run.
Вы видите функцию с сигнатурой M<T> -> T или сводимую к ней путем частичного применения.
Вы задумываетесь: можно ли к типу M<T> придумать функции bind и return такие, чтобы удовлетворять монадным правилам.
Если такие функции придумываются, то поздравляю, у вас монада.
Re: Монады
От: elmal  
Дата: 14.06.18 08:57
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Для каких именно практических нужд пригодны монады? и что называется монадой в языках, отличных от Хаскеля?

Вообще говоря, я понимаю монаду как хрень, для которой определены операции bind (то есть преобразовать объект в монаду) и flatMap, преобразующую эту монаду в последовательность других монад. Монады удобны тем, что позволяют выстраивать цепочки из нетривиальной логики достаточно элегантно. Например описывать цепочки асинхронных запросов, каллбек одного является параметром для следующего. Вместе с прокидыванием ошибок, вместе с обработки null и т.д. Основная выгода от них — они позволяют избавиться от кучи if, код в принципе выглядит стройнее, логичнее и короче. Минусы тоже есть — читаемость монад оставляет желать лучшего, понять что конкретно и как делается далеко не всегда тривиально, приходится напрягать мозги. Соответственно для многих вещей они весьма полезны. Но если можно обойтись без них, и некоторые вещи поддерживаются языком (например не Nullable типы позволяют обойтись без Maybe зачастую, функционал async await в языке позволяет строить цепочки асинхронных вызовов гораздо более читаемо, чем с помощью монад).

Соответственно для многих задач является если не панацеей, то наименьшим злом. Главное не увлекаться, во всем должно быть чувство меры.
Re[2]: Монады
От: dsorokin Россия  
Дата: 15.06.18 05:35
Оценка: 3 (1)
Здравствуйте, elmal, Вы писали:

E>Вообще говоря, я понимаю монаду как хрень, для которой определены операции bind (то есть преобразовать объект в монаду) и flatMap, преобразующую эту монаду в последовательность других монад. [..]


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

Есть простой способ разобраться с монадами — начать изучать общецелевой язык программирования Haskell, например, по вышедшей в этом году книге "Get Programming with Haskell": https://www.manning.com/books/get-programming-with-haskell
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.