Что такое монада? - PullRequest
       291

Что такое монада?

1330 голосов
/ 05 сентября 2008

Кратко рассмотрев недавно Хаскелла, каким было бы краткое, краткое, практичное объяснение того, что в сущности является монадой?

Я обнаружил, что большинство объяснений, с которыми я столкнулся, было довольно недоступным и лишено практических деталей.

Ответы [ 45 ]

31 голосов
/ 31 августа 2008

Монада, по сути, является формой «оператора типа». Это сделает три вещи. Сначала он «обернет» (или иным образом преобразует) значение одного типа в другой тип (обычно называемый «монадическим типом»). Во-вторых, он сделает все операции (или функции) доступными для базового типа доступными для монадического типа. Наконец, он обеспечит поддержку объединения себя с другой монадой для создания составной монады.

«Возможно, монада» по существу эквивалентна «обнуляемым типам» в Visual Basic / C #. Он принимает необнуляемый тип «T» и преобразует его в «Nullable », а затем определяет, что означают все двоичные операторы для Nullable .

Побочные эффекты представлены одинаково. Создается структура, которая содержит описания побочных эффектов наряду с возвращаемым значением функции. Затем «снятые» операции копируются вокруг побочных эффектов, когда значения передаются между функциями.

Они называются "монады", а не более простым для понимания именем "операторов типа" по нескольким причинам:

  1. Монады имеют ограничения на то, что они могут делать (подробности см. В определении).
  2. Эти ограничения, а также тот факт, что задействованы три операции, соответствуют структуре чего-то, называемого монадой в теории категорий, которая является неясной областью математики.
  3. Они были разработаны сторонниками "чистых" функциональных языков
  4. Сторонники чистых функциональных языков, таких как малопонятные разделы математики
  5. Поскольку математика неясна, а монады связаны с определенными стилями программирования, люди склонны использовать слово «монада» как своего рода тайное рукопожатие. Из-за этого никто не удосужился инвестировать в лучшее имя.
24 голосов
/ 20 мая 2009

Монады должны управлять потоком данных, как абстрактные типы данных для данных.

Другими словами, многим разработчикам нравится идея наборов, списков, словарей (или хешей, или карт) и деревьев. Внутри этих типов данных существует много особых случаев (например, InsertionOrderPreservingIdentityHashMap).

Однако, когда сталкиваются с «потоком» программы, многие разработчики не сталкиваются с гораздо большим количеством конструкций, чем if, switch / case, do, while, goto (grr) и (возможно) замыкания.

Итак, монада - это просто конструкция потока управления. Лучшей фразой для замены монады будет «тип управления».

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

Например, монада if:

if( clause ) then block

в самом простом случае имеет два слота - предложение и блок. Монада if обычно создается для оценки результата предложения и, если не ложно, для оценки блока. Многие разработчики не знакомы с монадами, когда они изучают «если», и просто нет необходимости понимать монады, чтобы писать эффективную логику.

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

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

Компиляторы могут иметь или не иметь поддержку пользовательских монад. Хаскелл, конечно, делает. Ioke имеет некоторые схожие возможности, хотя термин «монада» в языке не используется.

14 голосов
/ 30 августа 2008

Мой любимый учебник Монады:

http://www.haskell.org/haskellwiki/All_About_Monads

(из 170 000 обращений в поиске Google к "учебнику монад"!)

@ Stu: Смысл монад состоит в том, чтобы позволить вам добавить (обычно) последовательную семантику в чистый код; Вы даже можете создавать монады (используя Monad Transformers) и получать более интересную и сложную комбинированную семантику, например, например, анализ с обработкой ошибок, общим состоянием и журналированием. Все это возможно в чистом коде, монады просто позволяют абстрагировать его и повторно использовать в модульных библиотеках (всегда хороших в программировании), а также предоставляют удобный синтаксис, чтобы он выглядел обязательным.

В Haskell уже есть перегрузка операторов [1]: он использует классы типов во многом так же, как можно использовать интерфейсы в Java или C #, но в Haskell просто допускается использование не алфавитно-цифровых токенов, таких как + && и>, в качестве идентификаторов инфиксов. Это только перегрузка оператора, если вы имеете в виду «перегрузка точки с запятой» [2]. Звучит как чёрная магия, и возникает проблема с «перегрузкой точки с запятой» (представьте, что предприимчивые хакеры Perl узнают об этой идее), но суть в том, что без монад нет точки с запятой, поскольку чисто функциональный код не требует и не разрешает явная последовательность.

Все это звучит намного сложнее, чем нужно. Статья sigfpe довольно крутая, но для объяснения она использует Haskell, что не решает проблему курицы и яйца, заключающуюся в том, чтобы понять, как Haskell пытается обмануть монады, и понять, что монады могут обмануть Haskell.

[1] Это отдельная проблема от монад, но монады используют функцию перегрузки операторов Haskell.

[2] Это также упрощение, так как оператор для связывания монадических действий: >> = (произносится как «связать»), но есть синтаксический сахар («до»), который позволяет использовать фигурные скобки и точки с запятой и / или отступы и *. переводы строк 1018 *

9 голосов
/ 27 февраля 2014

Я все еще новичок в монадах, но я подумал, что поделюсь ссылкой, которую я нашел и которую очень приятно читать (С ФОТОГРАФИЯМИ !!): http://www.matusiak.eu/numerodix/blog/2012/3/11/monads-for-the-layman/ (без принадлежности)

По сути, теплая и нечеткая концепция, которую я получил из статьи, заключалась в том, что монады - это в основном адаптеры, которые позволяют разрозненным функциям работать в комбинируемой форме, т.е. иметь возможность объединять несколько функций, смешивать и сопоставлять их, не беспокоясь о несовместимых типах возврата и тому подобное. Таким образом, функция BIND отвечает за хранение яблок с яблоками и апельсинов с апельсинами, когда мы пытаемся создать эти адаптеры. А функция LIFT отвечает за использование функций «более низкого уровня» и «модернизацию» их для работы с функциями BIND, а также для их компоновки.

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

9 голосов
/ 12 декабря 2008

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

Если вы используете императивный язык и пишете некоторые выражения по порядку, код ВСЕГДА запускается именно в этом порядке.

И в простом случае, когда вы используете монаду, вы чувствуете то же самое - вы определяете список выражений, которые встречаются по порядку. Кроме того, в зависимости от того, какую монаду вы используете, ваш код может выполняться по порядку (как в монаде IO), параллельно по нескольким элементам одновременно (как в монаде списка), он может останавливаться на полпути (как в монаде Maybe) , он может приостановиться на полпути, чтобы быть возобновленным позже (как в монаде Возобновления), может перемотаться и начаться с начала (как в монаде Транзакции), или может перемотаться на полпути, чтобы попробовать другие варианты (как в монаде Логики) .

А поскольку монады полиморфны, можно запускать один и тот же код в разных монадах в зависимости от ваших потребностей.

Кроме того, в некоторых случаях возможно объединение монад (вместе с преобразователями монад) для одновременного получения нескольких функций.

8 голосов
/ 24 января 2009

В дополнение к превосходным ответам, приведенным выше, позвольте мне предложить вам ссылку на следующую статью (Патрик Томсон), которая объясняет монады, связывая концепцию с библиотекой JavaScript jQuery (и способ ее использования "метод цепочки" для управления DOM): jQuery - монада

Документация jQuery сама по себе не относится к термину «монада», но говорит о «шаблоне построителя», который, вероятно, более знаком. Это не меняет того факта, что у вас есть настоящая монада, может быть, даже не осознавая этого.

8 голосов
/ 27 декабря 2010

Монады - это не метафоры , но практически полезная абстракция, возникающая из общего паттерна, как объясняет Даниэль Спивак.

6 голосов
/ 13 июня 2010

Монада - это способ объединения вычислений в общий контекст. Это похоже на построение сети труб. При построении сети данные по ней не передаются. Но когда я закончил объединять все биты вместе с 'bind' и 'return', я вызываю что-то вроде runMyMonad monad data, и данные проходят по каналам.

6 голосов
/ 09 ноября 2015

На практике monad - это пользовательская реализация оператора композиции функций, которая заботится о побочных эффектах и ​​несовместимых входных и возвращаемых значениях (для формирования цепочки).

5 голосов
/ 16 сентября 2008

Если я правильно понял, IEnumerable является производным от монад. Интересно, может ли это быть интересным углом зрения для тех из нас, кто живет в мире C #?

Что бы это ни стоило, вот несколько ссылок на учебники, которые мне помогли (и нет, я все еще не понял, что такое монады).

...