В наши дни много говорят о монадах. Я прочитал несколько статей / постов в блоге, но я не могу зайти достаточно далеко с их примерами, чтобы полностью понять концепцию. Причина в том, что монады являются концепцией функционального языка, и поэтому примеры приведены на языках, с которыми я не работал (поскольку я не использовал функциональный язык в глубине). Я не могу понять синтаксис достаточно глубоко, чтобы полностью следовать статьям ... но я могу сказать, что есть кое-что, что стоит понять там.
Тем не менее, я хорошо знаю C #, включая лямбда-выражения и другие функциональные возможности. Я знаю, что C # имеет только подмножество функциональных возможностей, и поэтому, возможно, монады не могут быть выражены в C #.
Однако обязательно ли можно передать концепцию? По крайней мере, я на это надеюсь. Может быть, вы можете представить пример C # в качестве основы, а затем описать, чего бы разработчик C # хотел от него сделать, но не может, потому что в языке отсутствуют функциональные возможности программирования. Это было бы фантастически, потому что это передавало бы намерения и преимущества монад. Итак, вот мой вопрос: Как лучше всего объяснить монады разработчику C # 3?
Спасибо!
(РЕДАКТИРОВАТЬ: Кстати, я знаю, что по крайней мере 3 вопроса "что такое монада" уже есть на SO. Однако я сталкиваюсь с той же проблемой с ними ... так что этот вопрос нужен, по-моему, из-за разработчика C # Фокус. Спасибо.)
Ответы:
Большая часть того, что вы делаете в программировании в течение всего дня, - это объединение некоторых функций для создания из них более крупных функций. Обычно в вашем наборе инструментов есть не только функции, но и другие вещи, такие как операторы, присваивание переменных и т. П., Но в целом ваша программа объединяет множество «вычислений» в более крупные вычисления, которые в дальнейшем будут объединяться.
Монада - это некоторый способ сделать это «объединение вычислений».
Обычно ваш самый простой «оператор» для объединения двух вычислений
;
:Когда вы говорите это, вы имеете в виду «сначала делай
a
, потом делайb
». В результатеa; b
мы снова получаем вычисления, которые можно комбинировать с большим количеством вещей. Это простая монада, это способ объединения маленьких вычислений в большие.;
Говорит «делать то , что на левой стороне , а затем делать то , что по праву».Еще одна вещь, которую можно рассматривать как монаду в объектно-ориентированных языках, - это
.
. Часто вы найдете такие вещи:В
.
основном означает «вычислить вычисление слева, а затем вызвать метод справа в результате этого». Это еще один способ объединить функции / вычисления вместе, немного сложнее, чем;
. А концепция объединения вещей.
в единое целое - это монада, так как это способ объединения двух вычислений в новое вычисление.Другая довольно распространенная монада, которая не имеет специального синтаксиса, это шаблон:
Возвращаемое значение -1 указывает на ошибку, но нет никакого реального способа абстрагировать эту проверку ошибок, даже если у вас есть много API-вызовов, которые вам нужно объединить таким способом. По сути, это просто еще одна монада, которая объединяет вызовы функций по правилу «если функция слева вернула -1, вернем -1 сами, в противном случае вызовем функцию справа». Если бы у нас был оператор,
>>=
который делал это, мы могли бы просто написать:Это сделало бы вещи более читабельными и помогло бы абстрагировать наш особый способ объединения функций, чтобы нам не приходилось повторяться снова и снова.
И есть еще много способов комбинировать функции / вычисления, которые полезны в качестве общего шаблона и могут быть абстрагированы в монаде, позволяя пользователю монады писать гораздо более лаконичный и понятный код, поскольку весь бухгалтерский учет и управление используемые функции выполняются в монаде.
Например, вышеприведенное
>>=
может быть расширено, чтобы «выполнить проверку на ошибки и затем вызвать правую сторону сокета, который мы получили в качестве входных данных», так что нам не нужно явно указыватьsocket
много раз:Формальное определение немного сложнее, так как вам нужно беспокоиться о том, как получить результат одной функции в качестве входных данных для следующей, если эта функция нуждается в этом входе и поскольку вы хотите убедиться, что функции, которые вы комбинируете, вписываются в как вы пытаетесь объединить их в своей монаде. Но основная концепция заключается в том, что вы формализуете различные способы объединения функций вместе.
источник
;
примере: какие объекты / типы данных;
отображаются? (ПодумайтеList
картыT
вList<T>
) Как;
карта морфизмов / функций между объектами / типами данных? Чтоpure
,join
,bind
для;
?Прошел год с тех пор, как я разместил этот вопрос. После публикации я погрузился в Haskell на пару месяцев. Мне это очень понравилось, но я отложил его в сторону, как только я был готов погрузиться в Монады. Я вернулся к работе и сосредоточился на технологиях, необходимых для моего проекта.
И вчера вечером я пришел и перечитал эти ответы. Самое главное , я перечитал конкретный пример C # в текстовых комментариях к видео Брайана Бекмана, о котором кто-то упоминал выше . Это было настолько ясно и понятно, что я решил опубликовать это прямо здесь.
Из-за этого комментария я не только чувствую, что точно понимаю , что такое монады ... Я понимаю, что на самом деле написал на C # некоторые вещи, которые являются монадами ... или, по крайней мере, очень близкими, и стремлюсь решить те же проблемы.
Итак, вот комментарий - это все прямая цитата из комментария здесь по Сильван :
источник
Монада - это по существу отложенная обработка. Если вы пытаетесь написать код, который имеет побочные эффекты (например, ввод / вывод) на языке, который их не допускает, и допускает только чистые вычисления, один из уклонений заключается в том, чтобы сказать: «Хорошо, я знаю, что вы не будете делать побочные эффекты для меня, но не могли бы вы подсчитать, что произойдет, если вы сделали? "
Это своего рода обман.
Теперь это объяснение поможет вам понять общую картину намерений монад, но дьявол кроется в деталях. Как именно делать вы вычислить последствия? Иногда это не красиво.
Лучший способ дать представление о том, как кто-то привык к императивному программированию, - это сказать, что он помещает вас в DSL, в котором вместо этого используются операции, которые похожи на то, что вы привыкли вне монады, для создания функции, которая будет выполнять что вы хотите, если бы вы могли (например) записать в выходной файл. Почти (но не совсем), как если бы вы строили код в строку, чтобы потом быть eval'd.
источник
Maybe
иEither e
) и управления состоянием (State s
,ST s
) кажутся мне конкретными примерами «Пожалуйста, подсчитайте, что произойдет, если вы сделали [побочные эффекты для меня]». Другим примером будет недетерминизм ([]
).Я уверен, что другие пользователи будут публиковать подробные сообщения, но я нашел это видео полезным в некоторой степени, но я скажу, что я все еще не в состоянии свободно владеть концепцией, так что я мог (или должен) начать решать проблемы интуитивно с монад.
источник
Вы можете думать о монаде как о C #,
interface
которую должны реализовать классы . Это прагматичный ответ, в котором игнорируется вся теоретическая математика категорий, объясняющих, почему вы хотите использовать эти объявления в своем интерфейсе, и игнорируются все причины, по которым вы хотите иметь монады на языке, который пытается избежать побочных эффектов, но я обнаружил, что это хорошее начало для человека, который понимает (C #) интерфейсы.источник
Смотрите мой ответ "Что такое монада?"
Он начинается с мотивирующего примера, проходит через пример, выводит пример монады и формально определяет «монаду».
Он не предполагает никаких знаний о функциональном программировании и использует псевдокод с
function(argument) := expression
синтаксисом с простейшими возможными выражениями.Эта программа на C # является реализацией монады псевдокода. (Для справки:
M
является конструктором типа,feed
является операцией «связывания» и операциейwrap
«возврата».)источник