Монада в терминах непрограммирования

Возможный дубликат:
Что такое монада?

Как бы вы описали монаду в терминах непрограммирования? Есть ли какая-то концепция / вещь вне программирования (вне всего программирования, а не только FP), о которой можно сказать, что она действует или в значительной степени напоминает монаду?

10 ответов

Решение

Вот мой текущий удар в этом:

Монады ведро-бригады:

  1. Каждая операция - это человек, стоящий в очереди; то есть есть однозначная последовательность, в которой происходят операции.
  2. Каждый человек берет одно ведро в качестве входных данных, извлекает из него что-то новое и помещает в него новое. Ведро, в свою очередь, передается следующему человеку в бригаде (через связку, или >>=, операция).
  3. return Операция - это просто операция помещения вещей в ведро.
  4. В случае последовательности (>>) операции, содержимое корзины сбрасывается перед передачей следующему человеку. Следующего человека не волнует, что было в ведре, они просто ждут, чтобы его получить.
  5. В случае монад на (), билет передается внутри ведра. Это называется "Единица", и это просто чистый лист бумаги.
  6. В случае IO-монад каждый человек произносит что-то вслух, либо глубокое, либо глупое, но они могут говорить только тогда, когда держат ведро.

Надеюсь это поможет.:-)


Изменить: Я ценю вашу поддержку, но, к сожалению, проклятие Monad Tutorial снова ударил. Я описал только функциональное приложение с контейнерами, а не монады! Но я не нигилист - я верю, что проклятие Monad Tutorial может быть сломано! Итак, вот несколько более сложная картина, которая, я думаю, описывает ее немного лучше. Вы сами решаете, стоит ли брать с собой друзей.

Монады - это ведерная бригада с руководителями проектов. Руководители проектов стоят за всеми, кроме первого члена бригады. Члены бригады ведра сидят на стульчиках, и перед ними стоят ведра.

Первый человек получает что-то, делает с ним что-то и кладет в ведро. Этот человек тогда отдает руки - не следующему человеку в бригаде, это было бы слишком легко!:-) - но руководителю проекта, стоящему за этим человеком.

Руководитель проекта (ее зовут bind или >>=) берет ведро и решает, что с ним делать. Она может решить взять вещи первого человека из ведра и просто передать их человеку, стоящему перед ней, без лишних слов (это монада IO). Она может выбрасывать ведро и заканчивать бригаду (это fail). Она может решить просто обойти человека перед собой и передать ведро следующему менеджеру в бригаде без дальнейших церемоний (вот что происходит с Nothing в Maybe монада). Она может даже решить достать вещи из ведра и передать их человеку, стоящему перед ней, за один раз! (Это монада List.) В случае последовательности (>>) она просто постукивает по плечу человека, стоящего перед ней, вместо того, чтобы вручать им какие-либо вещи.

Когда следующий человек делает ведро с вещами, он передает его следующему менеджеру проекта. Следующий менеджер проекта снова выясняет, что делать с ведром, которое она дала, и передает вещи в ведре ее персоне. В конце ведро передается обратно по цепочке менеджеров проектов, которые могут по желанию делать вещи с ведром (например, List монада собирает все результаты). В результате первый менеджер проекта создает кучу вещей.

В случае с do Синтаксис, каждый человек на самом деле является операцией, которая определяется на месте в контексте всего, что было сделано раньше, - как будто менеджер проекта передает не только то, что находится в корзине, но также и значения (эээ, вещи), которые были сгенерированы предыдущие члены бригады. Построение контекста в этом случае гораздо проще увидеть, если вы выписываете вычисления, используя bind и sequence вместо использования do синтаксис - обратите внимание, что каждое последующее "утверждение" является анонимной функцией, созданной внутри операции, предшествующей этой точке.

() значения, монады ввода-вывода и return Операция остается описанной выше.

"Но это слишком сложно! Почему люди не могут сами разгрузить ведра?" Я слышал, вы спрашиваете. Ну, менеджер проекта может сделать кучу работы за кулисами, которая иначе усложнила бы работу человека. Мы пытаемся облегчить этим членам бригады, чтобы они не делали слишком много. Например, в случае монады Maybe каждый человек не должен проверять ценность того, что ему дают, чтобы увидеть, что ему ничего не дали - об этом позаботится руководитель проекта.

"Ну, тогда, если вы действительно пытаетесь облегчить работу каждого человека, почему бы не пойти до конца - пусть человек просто возьмет вещи и сдаст вещи, и пусть менеджер проекта будет беспокоиться о начальном этапе?" Это часто делается, и у него есть специальное имя, называемое поднятием человека (э-э, операция) в монаду. Иногда, тем не менее, вы хотите, чтобы у человека было что-то более сложное, где он хотел бы получить некоторый контроль над производимым контейнером (например, нужно ли ему возвращаться). Nothing в случае Maybe монада), и вот что обеспечивает монада в полной общности.

Точки, являющиеся:

  1. Операции являются последовательными.
  2. Каждый человек знает, как делать ведра, но не умеет доставать вещи из ведер.
  3. Каждый руководитель проекта знает, как обращаться с ведрами и как извлечь из них что-то, но ему все равно, что в них.

Так заканчивается мой учебник перед сном.:-П

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

Джо Хаскеллер пытается узнать о монадах. После недолгого понимания их, просмотра примеров, написания кода, чтения того, что написали другие люди, у него наконец наступил момент "ага!": Все внезапно прояснилось, и Джо понимает монады! Конечно, на самом деле произошло то, что мозг Джо соединил все детали в абстракцию более высокого уровня, метафору, которую Джо может использовать для интуитивного понимания монад; давайте предположим, что метафора Джо в том, что монады похожи на буррито. Вот где Джо плохо интерпретирует свой собственный мыслительный процесс: "Конечно!" - думает Джо. "Теперь все так просто. Ключ к пониманию монад в том, что они похожи на буррито. Если бы только я думал об этом раньше! "Проблема, конечно, в том, что если бы Джо подумал об этом раньше, это бы не помогло: неделя проработки деталей была необходимой и неотъемлемой частью формирования интуиции Джо в буррито. не печальное последствие его неудачной попытки дойти до идеи раньше.

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

Как я уже говорил в другом ответе давным-давно, статья sigfpe " Вы могли бы изобрести монады" ! (И, возможно, у вас уже есть.), А также оригинальная статья Филипа Уодлера " Монады для функционального программирования" являются отличными введениями (которые дают не аналогии, а множество примеров), но помимо этого вы просто продолжаете кодировать, и в конце концов все это будет казаться тривиальный.

[Неверный ответ: одно место монады существуют вне всего программирования, конечно, в математике. Как указывает этот веселый пост, "монада - это моноид в категории эндофункторов, в чем проблема?":-)]


Редактировать: Спрашивающий, похоже, интерпретировал этот ответ как снисходительный, говоря что-то вроде "Монады настолько сложны, что они не поддаются аналогии". На самом деле ничего подобного не было задумано, и это монада-аналогии, которые часто кажутся снисходительными. Может быть, мне следует перефразировать мою точку зрения как " Вы не должны понимать монады ". Вы используете определенные монады, потому что они полезны - вы используете монаду Maybe, когда вам нужны типы Maybe, вы используете монаду IO, когда вам нужно выполнить IO, аналогично другим примерам, и, очевидно, в C# вы используете шаблон Nullable<>, LINQ, понимание запросов и т. Д. Теперь, понимание того, что в основе всех этих структур лежит одна общая абстракция, которую мы называем монадой, необязательно понимать или использовать конкретные монады. Это что-то, что может прийти в качестве запоздалой мысли после того, как вы увидели более одного примера и распознали шаблон: обучение переходит от конкретного к абстрактному. Непосредственное объяснение абстракции путем обращения к аналогиям самой абстракции обычно не помогает учащемуся понять, что это за абстракция.

С точки зрения непрограммирования:

Если F и G - пара сопряженных функторов, причем F слева присоединена к G, то композиция GF является монадой.

Есть ли какая-то концепция / вещь вне программирования (вне всего программирования, а не только FP), о которой можно сказать, что она действует или в значительной степени напоминает монаду?

Да на самом деле есть. Монады прямо связаны с "возможностью" в модальной логике расширением изоморфизма Карри-Ховарда. (См.: Судебная реконструкция модальной логики.)

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

Основная идея состоит в том, что без монад все выражения существуют в одном и том же мире, и все вычисления выполняются в этом мире. Но с монадами может быть много миров, и расчет движется между ними. (например, каждый мир может указывать текущее значение некоторого изменяемого состояния)

С этой точки зрения, монада p означает "в возможном достижимом мире из текущего мира".

В частности, если t это тип тогда:

x :: t означает, что что-то типа T непосредственно доступно в современном мире
y :: p t означает что-то типа t доступно в мире, достижимом из текущего

Затем, return позволяет нам использовать текущий мир как достижимый.

return :: t -> p t

А также >>= позволяет нам использовать что-то в достижимом мире и затем достигать дополнительных миров из этого мира.

(>>=) :: p t -> (t -> p s) -> p s

Так >>= может быть использован для построения пути к достижимому миру из меньших путей через другие миры.

С мирами, похожими на состояния, это довольно легко объяснить. Для чего-то вроде монады ввода-вывода это также довольно просто: мир определяется всеми взаимодействиями программы с внешним миром.

Для не прекращения достаточно двух миров - обычного и бесконечно далекого в будущем. (Применение >>= со вторым миром разрешено, но вы вряд ли будете наблюдать за тем, что происходит в этом мире.) Для монады продолжения мир остается тем же, когда продолжения используются нормально, и есть дополнительные миры, когда они нет (например, для callcc).

Из этого отличного поста Майка Ванье,

Одним из ключевых понятий в Haskell, который отличает его от других языков программирования, является понятие "монады". Люди, кажется, находят это трудным для изучения (я тоже так делал), и в результате в Интернете появилось множество учебных пособий по монадам, некоторые из которых очень хороши (особенно мне нравится All About Monads Джеффа Ньюберна). Говорят даже, что написание учебника по монадам - ​​это обряд для начинающих программистов на Haskell. Тем не менее, одна большая проблема со многими учебниками монад заключается в том, что они пытаются объяснить, что монады имеют отношение к существующим концепциям, которые читатель уже понимает (я даже видел это в презентациях Саймона Пейтона-Джонса, главного автора компилятора GHC). и генерал Хаскелл Гранд Пообах). Это ошибка, и я собираюсь рассказать вам, почему.

Естественно, когда пытаешься объяснить, что есть что-то, объяснить это ссылкой на вещи, о которых другой человек уже знает. Это хорошо работает, когда новая вещь в чем-то похожа на вещи, знакомые другому человеку. Он полностью разрушается, когда новая вещь полностью вне опыта человека, изучающего ее. Например, если бы вы пытались объяснить, что такое огонь пещерному человеку, который никогда не видел огня, что бы вы сказали? "Это как нечто среднее между воздухом и водой, но горячо..." Не очень эффективно. Аналогично, объяснение того, что представляет собой атом с точки зрения квантовой механики, проблематично, потому что мы знаем, что электрон на самом деле не вращается вокруг ядра, как планета вокруг звезды, и понятие "делокализованное электронное облако" на самом деле не имеет много значат Фейнман однажды сказал, что никто на самом деле не понимает квантовую механику, и на интуитивном уровне это правда. Но на математическом уровне квантовая механика хорошо понята; у нас просто нет хорошей интуиции для того, что на самом деле означает математика.

Какое это имеет отношение к монадам? Снова и снова, в уроках, сообщениях в блогах и в списках рассылки на Haskell я видел монады, объясненные одним из двух предположительно интуитивно понятных способов: монада - это "что-то вроде действия" или "что-то вроде контейнера". Как что-то может быть как действием, так и контейнером? Разве это не отдельные понятия? Монада - это какой-то странный "активный контейнер"? Нет, но дело в том, что утверждение, что монада - это вид действия или вид контейнера, неверно. Так что же такое монада?

Вот ответ: Монада - это чисто абстрактное понятие, не имеющее принципиальной связи ни с чем, о чем вы, возможно, когда-либо слышали. Понятие монады происходит от теории категорий, которая является наиболее абстрактной областью математики, которую я знаю. Фактически, весь смысл теории категорий состоит в том, чтобы абстрагировать всю структуру математики, чтобы выявить сходства и аналогии между внешне несопоставимыми областями (например, между алгеброй и топологией), с тем чтобы объединить математику в ее фундаментальные понятия и таким образом уменьшить избыточность. (Я мог бы говорить об этом довольно долго, но я бы предпочел вернуться к сути, которую я пытаюсь сформулировать.) Поскольку я предполагаю, что большинство программистов, изучающих Хаскель, мало знают о теории категорий, монадах не будут ничего значить для них. Это не значит, что им нужно изучать теорию категорий, чтобы использовать монады в Haskell (к счастью), но это означает, что им нужно научиться думать о вещах более абстрактно, чем они, вероятно, привыкли.

Пожалуйста, перейдите по ссылке вверху поста, чтобы прочитать статью полностью.

На практике большинство монад, с которыми я работал, ведут себя как некий неявный контекст.

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

Конечно, вы можете поговорить с вашим боссом (а не с вашим другом) о вашем менеджере уровня пропуска (а не о вашем друге), которого зовут Боб. Здесь вы можете поговорить еще раз, опять же с некоторой подразумеваемой коннотацией, которая имеет смысл только в контексте разговора. Вы даже можете произнести те же слова, что и со своим другом, но они будут иметь другое значение из-за другого контекста.

В программировании тоже самое. Способ, которым tell поведение зависит от того, в какой монаде вы находитесь; способ сбора информации (>>=) зависит от того, в какой монаде вы находитесь. Та же идея, другой способ разговора.

Черт, даже правила разговора могут быть монадическими. "Не говори никому, что я тебе сказал" скрывает информацию так же, как runST предотвращает выход ссылок из ST монада. Очевидно, что разговоры могут иметь слои и слои контекста, точно так же, как у нас есть стеки монадных преобразователей.

Надеюсь, это поможет.

Хорошо, вот хорошее подробное описание монад, которые определенно выходят за рамки всего программирования. Я знаю, что это за пределами программирования, потому что я программист, и я не понимаю даже половины того, о чем это говорит.

На YouTube также есть серия видеороликов, объясняющих монады этого сорта - вот первая в этой последовательности.

Я предполагаю, что это не совсем то, что вы искали, хотя...

Это зависит от того, с кем вы разговариваете. Любое объяснение должно быть представлено на правильном уровне. Мое объяснение инженеру-химику будет отличаться от моего объяснения математику или финансовому менеджеру.

Лучший подход состоит в том, чтобы связать это с чем-то из опыта человека, с которым вы разговариваете. Как правило, секвенирование является довольно универсальной проблемой, поэтому постарайтесь найти что-то, о чем человек знает, где вы говорите: "сначала делай X, потом делай Y". Затем объясните, как с этим сталкиваются обычные языки программирования; если вы говорите "делай X, то делай Y" компьютеру, он делает X и Y немедленно, не дожидаясь дальнейшего ввода, но в то же время он не может сделать Z для кого-то другого; компьютерная идея "а потом делай" отличается от твоей. Таким образом, программисты должны писать свои программы не так, как вы (эксперт) объясняете это. Это создает разрыв между тем, что вы говорите, и тем, что говорит программа. Чтобы преодолеть этот разрыв, нужно время и деньги.

Монады позволяют помещать вашу версию "и затем делать" в компьютер, так что вы можете сказать "делайте X, а затем делайте Y", и программист может написать "до {x; y}", и это означает, что вы имеете в виду.

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

Да, Monads происходит от концепции вне haskell. У Haskell есть много терминов и идей, которые были заимствованы из теории категорий. Это одна из них. Поэтому, если этот человек, который не является программистом, оказывается математиком, изучавшим теорию категорий, просто скажите: "Монада - это моноид в категории эндофункторов".

Другие вопросы по тегам