Haskell

Jul 24, 2012 12:51

Я всё таки решил попробовать на этом вашем хаскеле написать хотя бы 10 строчек кода ( Read more... )

Leave a comment

levgem July 24 2012, 15:18:04 UTC
Давай попробую.

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

С её помощью иммитируется состояние

Reply

hmepas July 24 2012, 15:20:52 UTC
При этом под словом "следующий" мы имеем ввиду справа на лево, так?

Fnext( Fprevious(x) ) - правильно понял идею?

Reply

levgem July 24 2012, 15:25:24 UTC
Не совсем.

Есть несколько функций: f1(x1), f2(x2), f3(x3) ...

Например, это POSIX call-ы или что-то ещё в твоём алгоритме.

Ты видишь, что ты запускаешь первую функцию и на основании результатов её работы решаешь, вызывать вторую или нет. Потом то же самое с третьей. Т.е. у тебя возникает управляющая логика, которая поочередно запускает функцию за функцией и результат их работы каким-то образом обрабатывает и анализирует.

И тогда ты шмак и делаешь монаду, например, catch_error:

catch_error([f1, f2, f3, f4], initial_value).

Где initial_value - это то, что будет отдано в f1(x1). Эта монада будет устроена так: она запустит f1 с initial_value, проверит результат, запустит f2, если не было ошибки. И т.п.

То, что ты привел, безусловно вызовет Fnext, а это надо не допустить.

Reply

hmepas July 24 2012, 15:29:28 UTC
Получается что когда я думал что монады это что-то вроде grep/sort/map в перле или comprehensive lists в python я был не далек от правды. С той лишь разницы, что у монады один "агрумент" и несколько функций, в то время как у map { # code } @list все наоборот -- код который пробегает по списку функций, передавая им агрумент.

Reply

levgem July 24 2012, 15:30:27 UTC
Насколько я понимаю, тут монада имеет полный контроль над тем, вызывать следующую функцию или нет и с какими данными.

Reply

hmepas July 24 2012, 16:04:04 UTC
ну вроде понятно. во всяком случае такое объяснение мне много более понятно чем те многостраничные документы которые я читал до этого.

Reply

kurilka July 24 2012, 15:39:28 UTC
То, о чём ты говоришь не нуждается в монадах и решается чистыми способами: как пример - map (\f -> f 1) [sin,cos], вполне себе список функций и "пробегает".

Reply

antilamer July 24 2012, 15:54:13 UTC
Это в общем довольно близко к истине. Действительно, чтобы задать монаду, почти достаточно задать операцию (.) :: (b -> m c) -> (a -> m b) -> (a -> m c) (синтаксическая анонимность этих функций не имеет никакого значения - это просто функции). Вообще такая штука называется "стрелка" и требует определения еще пары операций (чтобы из стрелок можно было строить эдакий граф dataflow), но стрелки это обобщение монад.

Reply

levgem July 24 2012, 17:17:53 UTC
Женя. При всём уважении, «достаточно задать операцию (.) :: (b -> m c) -> (a -> m b) -> (a -> m c)» - это не объяснение, а цитата из посредственного учебника, которыми забиты полки в Университете. Т.е. объяснить - это на простых понятиях объяснить более сложные вещи.

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

Например, мне слова про «b -> m c» вообще ничего не говорят. Когда я вижу это, я закрываю и дальше не читаю, потому что не знаю этого языка и совершенно точно знаю, что здесь обсуждают простые вещи неизвестным мне языком.

Паша попросил объяснить непростые вещи простым языком. Есть подозрение, что ты выбрал не очень простой язык.

Reply

antilamer July 24 2012, 17:53:02 UTC
Хм, ок, я использовал эту нотацию т.к. думал, что она будет тебе понятна, раз ты уже начал писать на Haskell - это обыкновенная нотация типов в Haskell.

Давай тогда ограничимся просто первой фразой - твое понимание достаточно близко к истине :) Действительно, монада это способ сцеплять друг с другом вычисления вида "принимает на вход некий параметр и вычисляет вход для следующего вычисления", где "вычисляет" может обозначать разные вещи в зависимости от монады: либо "просто вычисляет, но с побочными эффектами" (IO), либо "порождает несколько результатов" (List), либо "порождает результат либо ошибку" (Maybe / Either / Error), либо "парсит", либо "вычисляет асинхронно", и т.п.

Reply

djuffin July 25 2012, 03:00:21 UTC
Перегрузка операции точка с запятой ;)

Reply


Leave a comment

Up