Монады
От: Mirrorer  
Дата: 08.02.07 06:20
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ> сейчас, я например вижу, что многие люди, не знакомые с хаскелом, считают, что монады — это только способ имитации императивности. а ведь на самом деле это ещё 30-40 кг легкоусвояемого вкуснячика!


Так-с... А здесь попрошу поподробнее.. Я думаю такая тема будет интересна многим.
... << RSDN@Home 1.2.0 Propellerheads — Cominagetcha >>

09.02.07 15:35: Ветка выделена из темы Исключительно философский вопрос.
Автор: Зверёк Харьковский
Дата: 07.02.07
— AndrewVK
15.02.07 02:01: Перенесено модератором из 'Философия программирования' — Хитрик Денис
Re: Монады
От: BulatZiganshin  
Дата: 08.02.07 08:42
Оценка:
BZ>> сейчас, я например вижу, что многие люди, не знакомые с хаскелом, считают, что монады — это только способ имитации императивности. а ведь на самом деле это ещё 30-40 кг легкоусвояемого вкуснячика!

M>Так-с... А здесь попрошу поподробнее.. Я думаю такая тема будет интересна многим.


если ты серьёзно, то самый простой способ — посмотреть спсиок писем, которые я написал (или даже только тех, за которые меня наградили)
Люди, я люблю вас! Будьте бдительны!!!
Re[2]: Монады
От: Mirrorer  
Дата: 08.02.07 09:38
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>если ты серьёзно, то самый простой способ — посмотреть спсиок писем, которые я написал (или даже только тех, за которые меня наградили)


На самом деле внимательно слежу за твоими постами

Наверное нужно точнее сформулировать вопрос..
Что такое Хаскелевые монады я в принципе представляю. Даже пытался изобразить нечто похожее на C#
здесь
Автор: Mirrorer
Дата: 30.10.06


Но общее впечатление пока от них — исключительно имеративные возможности в Хаскеле + некий паттерн чтоли. Ну вот не удалось мне увидеть пока чего-то большего.

Поясню как я их вижу.

Монада — это класс реализующий интерфейс IMonad, с >>=, return и т.д. а также удовлетворяющий монадическим законам. С этим понятно.

Есть монада State. С ней тоже вроде все понятно состояние и состояние. Его можно передавать по цепочке в неизменном виде, а можно и изменить.

Как только у нас появилась монада State мы можем делать IO. IO тот же State, только в состоянии хранится вся информация необходимая для ввода-вывода. Хендлы открытых файлов, этц. Естественно все это спрятано внутри монады и снаружи все выглядит как обычный интерфейс IMonad(в ООП-шном смысле).

С List-ом тоже вроде понятно. Это реализация интерфейса IMonad только List-специфичная. Вот чего не могу понять что в этом особенного?

Ну есть допустим в .NET интерфейс IEnumerable, который позволяет представлять все что угодно в Enumer-абельном виде. Ну здорово кто же спорит. Но ведь подобных интерфейсов вагон и маленькая тележка....

Я к чему вообще. Скорее всего в моем понимании монад есть какой-то недостаток. То есть я вижу в монаде исключительно IMonad и не более того. Не вижу 40 кг легоусваяемости
Поэтому и хочется чтобы меня ткнули куда-то носом или долбанули палкой по башке в лучших традициях дзен буддизма чтобы снизошло на меня просветление

З.Ы. А "All about monads" на которую ты давал ссылку
тута
Автор: BulatZiganshin
Дата: 07.02.07
я знаю и люблю. Собственно по ней и грокал монады..
... << RSDN@Home 1.2.0 КИНО — Просто хочешь ты знать >>
Re: Монады
От: Last Cjow Rhrr Россия lj://_lcr_
Дата: 08.02.07 09:52
Оценка:
Mirrorer,

BZ>> сейчас, я например вижу, что многие люди, не знакомые с хаскелом, считают, что монады — это только способ имитации императивности. а ведь на самом деле это ещё 30-40 кг легкоусвояемого вкуснячика!


M>Так-с... А здесь попрошу поподробнее.. Я думаю такая тема будет интересна многим.


Вот-с кратенький такой список:

Продолжения
Обработка исключений
ГУИ
Логгинг
Коммуникации между процессами
Парсеры
Интерпретаторы
Энергичное исполнение кода
Интерфейс к коду на других языках (FFI)

http://en.wikipedia.org/wiki/Monads_in_functional_programming#Others
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Монады
От: Mirrorer  
Дата: 08.02.07 11:37
Оценка:
Здравствуйте, Last Cjow Rhrr, Вы писали:

LCR>Вот-с кратенький такой список:

(Список нагло изничтожен)

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

Можно конечно смотреть сырцы всяких там Parsec-ов, но это долго и непродуктивно Допустим плюсы ООП-шных паттернов мне видны без увеличительного стекла. А вот с монадами что-то не складывается Хочется верить что это временно
... << RSDN@Home 1.2.0 silent >>
Re[3]: Монады
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 08.02.07 11:42
Оценка:
Здравствуйте, Mirrorer, Вы писали:

M>Я к чему вообще. Скорее всего в моем понимании монад есть какой-то недостаток. То есть я вижу в монаде исключительно IMonad и не более того. Не вижу 40 кг легоусваяемости :(


Да всё у тебя верно с пониманием. Неверно понимать монады исключительно как императив.
Монада — это IMonad, которую может реализовать не только поледовательное вычисление, но и вычисление с возможным результатом, вычисление с несколькими результатами, бэктрекинг, STM, даже вот Logic монада есть и целая толпа других вычислений.
Re[2]: Монады
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 08.02.07 11:50
Оценка: +1
Здравствуйте, Last Cjow Rhrr, Вы писали:

LCR>Продолжения

LCR>Обработка исключений
LCR>ГУИ
LCR>Логгинг
LCR>Коммуникации между процессами
LCR>Парсеры
LCR>Интерпретаторы
LCR>Энергичное исполнение кода
LCR>Интерфейс к коду на других языках (FFI)

Бэктрекинг
Логика
STM
Multiresult
optional result
случайные значения
недетерминированность

да и самому можно толпу придумать — например, упорядочивание результатов, или для моделирования устройств — вычисления с тактами, ну и т.д.
Re[3]: Монады
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 08.02.07 11:57
Оценка:
Здравствуйте, Mirrorer, Вы писали:

M>Не, доктор, я то все понимаю. Но все прелести в списке можно вполне реализовать без монад.


Да можно, конечно. Прелести обычные, те, что мы видим у использования общего интерфейса — возможность работать с вычислением, не задумываясь что это за вычисление, возможность объединять эти вычисления общим способом и т.д.
Re[3]: Монады
От: BulatZiganshin  
Дата: 08.02.07 12:17
Оценка: 80 (12)
LCR>>Вот-с кратенький такой список:
M>(Список нагло изничтожен)

M>Не, доктор, я то все понимаю. Но все прелести в списке можно вполне реализовать без монад.

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

M>Можно конечно смотреть сырцы всяких там Parsec-ов, но это долго и непродуктивно


на самом деле монады — очень простая штука. вот здесь — http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html — объяснено, что это такое

если посмотреть на императивный яхык и взять в нём конструкцию типа

do { x<-a; y<-b; c }


то какой смысл здесь можно придать точке с запятой? это конструкция последовательного выполнения, и она всегда таковой остаётся, без вариантов. а что если эту ';' сделать интерфейсом, и позволить писать всякие её реализации, которые можно успешно использовать с всё тем же кодом?

монады это и есть обощённый интерфейс, позволяющий придавать этой точке с запятой самые рахличные смыслы (ну ты наврно в курсе, что в хаскел вышеупомянутое транслируется в

a >>= (\x -> b >>= (\y -> c ))


и разный смысл предаётся этому '>>=')

parsec как раз вполне подходящий пример, и ты в курсе наверно, что когда в boost включили аналогичную библиотеку, то им пришлдось сэмулировать и lazy evaluation, и как я понимаю parsing monad, чтобы добиться тех же возможностей с бэктрекингом. заметь, что подобных бибилиотек, позволяющих описывать парсер средствами обычного языка, а не использовать кодогенератор типа yacc, в других языках просто нет



другой классический пример — поиск значений в базе. без монад его можно записать как:

find x y = case (lookup base x) of
             Nothing -> Nothing
             Just a  -> case (lookup base y) of
                          Nothing -> Nothing
                          Just b  -> Just (a+b)


с монадой же он выглядит как:

find x y = do a <- lookup base x
              b <- lookup base y
              return (a+b)


при этом монада Maybe вступает в дело автоматически и обеспечивает, что при возвращении Nothing любым поиском дальнейшие вычисления скипаются и возвращается Nothing как общий результат. собюственно, вышенаписанный код и описывает как будет выглядеть ниженаписанный после рассахаривания. понятно, что при этом испольуется другая реализация всё той же >>=, реализация из instance Monad Maybe

если же lookup будет возвращать список найденных элементов, то этот код волшебным образом начнёт возвращать список их сумм и это уже будет эквивалентно list comprehension:

find x y = [ a+b | a <- lookup base x, b <- lookup base y ]


собтвенно, в хаскел одно время можно было записывать в синтаксисе list comprehension вычисления в любых монадах, потом это убрали, чтоб не путать новичков сложными error messages
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: Монады
От: Last Cjow Rhrr Россия lj://_lcr_
Дата: 08.02.07 12:25
Оценка: +1
Mirrorer,

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


Пока я только-только продравшись сквозь YAHT чувствую на уровне мозжечка, что монады — любопытная штука, позволяющая внешним по отношению к коду образом вносить структуру в программу и влиять на поведение. Но чтобы поговорить более предметно, мне нужно поковыряться с ними побольше. Так что не сейчас.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[4]: Монады
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 08.02.07 12:34
Оценка: :)
Здравствуйте, Last Cjow Rhrr, Вы писали:

LCR>Пока я только-только продравшись сквозь YAHT чувствую на уровне мозжечка, что монады — любопытная штука, позволяющая внешним по отношению к коду образом вносить структуру в программу и влиять на поведение. Но чтобы поговорить более предметно, мне нужно поковыряться с ними побольше. Так что не сейчас. :-)


Значит тебя ещё ждут приключения с комонадами и стрелками :-)
Re[5]: Монады
От: Last Cjow Rhrr Россия lj://_lcr_
Дата: 08.02.07 12:39
Оценка:
lomeo,

L>Значит тебя ещё ждут приключения с комонадами и стрелками


Да-а, уже слюнки потекли...
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[4]: Монады
От: BulatZiganshin  
Дата: 08.02.07 12:45
Оценка:
LCR>Пока я только-только продравшись сквозь YAHT чувствую на уровне мозжечка, что монады — любопытная штука, позволяющая внешним по отношению к коду образом вносить структуру в программу и влиять на поведение. Но чтобы поговорить более предметно, мне нужно поковыряться с ними побольше. Так что не сейчас.

продравшись? а ведь yaht считается самым порстым и доходчивым мануалом

проблема в том, что трудно понять, что читать дальше; нет какого-то чёткого мануала следующего уровня. во всяком случае, не монады — имхо это не настолько важная и интересная вещь

если вас интересует практическое, "системное" прогшраммирование — то однозначно "awkward squad"

если хотите подывиться на то, чего у девочек нет в приницпе — почитайте "introduction to parsec", http://www.cs.uu.nl/~daan/download/parsec/parsec.html

свои "IO Inside" и "OOP мы type calsses" я наверно уже перерекламировал но по крайней мере в первом приводятся примеры того, как использовать фукнциоланльный подход и к императивному программированию. а второе необходимо порчесть когда вы всерьёз заинтересуетесь type классами — они только с виду похожи на C++-ные
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: Монады
От: Last Cjow Rhrr Россия lj://_lcr_
Дата: 08.02.07 12:57
Оценка:
Bulat,

BZ>свои "IO Inside" и "OOP vs type classes" я наверно уже перерекламировал


Спасибо, теперь страна знает своих героев
И то, и то я прочитал, да и функциональный подход сам люблю.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[5]: Монады
От: Mirrorer  
Дата: 08.02.07 13:52
Оценка: +1
Здравствуйте, BulatZiganshin, Вы писали:

BZ>продравшись? а ведь yaht считается самым порстым и доходчивым мануалом


Начало у него действительно отличное. Но допустим раздел Continuation Passing Style я так и не понял. Сумбурно как-то. И монады тоже не идеально описаны ИМХО. All about monads в этом плане гораздо лучше..
... << RSDN@Home 1.2.0 silent >>
Re[3]: и опять о монадах
От: palm mute  
Дата: 08.02.07 13:56
Оценка: 196 (14)
Mirrorer wrote:
>

> Можно конечно смотреть сырцы всяких там Parsec-ов, но это долго и

> непродуктивно Допустим плюсы ООП-шных паттернов мне видны без
> увеличительного стекла. А вот с монадами что-то не складывается Хочется
> верить что это временно

Ну, попробую я. Надо, в конце концов, закрепить за собой статус haskell
newbie .

Попробуй посмотреть на оператор bind как обобщение композиции. При
композиции функций мы получаем новую функцию (f.g). Для вычисления
значения (f.g) x результат вычисления (g x) передается функции f. Все
элементарно.

Отличие монадных действий от функций:
1) помимо аргументов, они неявно получают некое состояние
2) могут генерировать меньше/больше одного результата
3) могут оказывать эффект на состояние

Чтобы обобщить композицию функций до композиции действий, нужно
1) протаскивать состояние
2) для выражения 'g >>= f' f может выполняться столько раз, сколько
результатов было получено в результате вычисления g.

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

Вот и все. Если функцию (f.g.h.u) можно рассматривать как конвейер, в
котором каждый из элементов конвейера получает результаты обработки на
предыдущем шаге, то действие (u >>= h >>= g >>= f) в общем случае
является деревом конвейеров, с потенциально тупиковыми ветками, причем в
каждой ветке место одной ленты конвейера у нас есть 2 параллельные
ленты: по одной ленте передаются аргументы/результаты вычислений, как и
в случае функций, по второй передается неявное состояние.

Что мы получаем от такой абстрактной конструкции? Повторюсь, это важно:
возможность композиции. Возможность получить из элементарных шагов
вычисления более крупные вычисления, определив в единственном месте
программы, как эта композиция должна работать.

Простой пример. Представим, что у нас есть процедуры foo, bar, baz,
которые для вычисления результата должны иметь доступ к некоторому
контексту ctx. Что мы делаем в ОО-программе? Если foo, bar, baz — методы
одного класса Blabla, и разделение контекста нам нужно только в пределах
одного объекта, все просто — мы добавляем приватное поле ctx в класс
Blabla. Если классов или объектов много, начинаются сложности — явная
передача параметра ctx в конструкторы или методы, синглтоны,
ServiceProvider'ы и т.д.

А вот как проблема решается при помощи монады Reader:
import Control.Monad
import Control.Monad.Reader
import Text.Printf

foo :: Int -> Reader String String
foo x = do
   ctx <- ask
   return $ printf "foo %d called with ctx=%s" x ctx

bar :: Int -> Reader String String
bar x = do
   ctx <- ask
   return $ printf "bar %d called with ctx=%s" x ctx

baz :: Int -> Reader String String
baz x = do
   ctx <- ask
   return $ printf "bar %d called with ctx=%s" x ctx


combineOutputs actions = do
   results <- sequence actions
   return $ unlines results

run ctx actions = do
   putStrLn $ (runReader (combineOutputs actions) ctx)
   putStrLn "======================================"


main = do
   run "context1" [foo 1, bar 1]
   run "context2" [baz 2, foo 2, foo 1, bar 5]
   run "context3" [bar 7]


Вывод:
foo 1 called with ctx=context1
bar 1 called with ctx=context1

======================================
bar 2 called with ctx=context2
foo 2 called with ctx=context2
foo 1 called with ctx=context2
bar 5 called with ctx=context2

======================================
bar 7 called with ctx=context3

======================================


Для разделения контекста между действиями a и b достаточно объединить их
в один do-блок: runReader (do { a; b }) ctx, причем a и b могут
находиться на различной глубине стека вызовов.

Надеюсь, хоть чуть-чуть понятнее стало .
Posted via RSDN NNTP Server 2.0
Re[6]: Монады
От: BulatZiganshin  
Дата: 08.02.07 14:11
Оценка: +1 :))
BZ>>продравшись? а ведь yaht считается самым порстым и доходчивым мануалом

M>Начало у него действительно отличное. Но допустим раздел Continuation Passing Style я так и не понял. Сумбурно как-то. И монады тоже не идеально описаны ИМХО. All about monads в этом плане гораздо лучше..


cps, монады, type classes я бы посчитал продвинутым материалом, которому там не место. но тут конечно надо знать, что там читать, а что скипать я в своё время бросил изучать хаскел из-за того, что в gentle глава о монадах была написана с особым цинизмом
Люди, я люблю вас! Будьте бдительны!!!
Re[4]: и опять о монадах
От: BulatZiganshin  
Дата: 08.02.07 14:18
Оценка:
>> увеличительного стекла. А вот с монадами что-то не складывается Хочется
>> верить что это временно

PM>Ну, попробую я. Надо, в конце концов, закрепить за собой статус haskell

PM>newbie .

отличное описание! то, что я конце концов понял, прочитав мириад разных тюториалов, вы сформулировали коротко и точно, подчеркнув самую суть
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: Монады
От: Mirrorer  
Дата: 08.02.07 14:20
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Значит тебя ещё ждут приключения с комонадами и стрелками


А вот такой вопросец. Комонады и стрелки изучать лучше после прокачки в ТК или и без ТК нормально пойдет?
... << RSDN@Home 1.2.0 silent >>
Re[5]: и опять о монадах
От: palm mute  
Дата: 08.02.07 14:23
Оценка:
BulatZiganshin wrote:
> отличное описание! то, что я конце концов понял, прочитав мириад разных
> тюториалов, вы сформулировали коротко и точно, подчеркнув самую суть

Спасибо . Для меня большая честь получить такой отзыв от автора
библиотек, попавших в репозиторий darcs.haskell.org.
Posted via RSDN NNTP Server 2.0
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.