Я читал некоторые документы в Интернете, которые пытались представить концепцию монады для программистов Схемы. Основная идея заключалась в том, что в неимперативном программировании монады используются для выражения «потока вычислений», то есть для обеспечения последовательной оценки выражений. Тогда это поразило меня: поскольку тело лямбда-выражения оценивается последовательно, нужно ли понимать, что монады будут излишними в Схеме? Являются ли лямбда-тела по-разному оценены на других языках (например, Haskell или ML)?Лямбда выражения как монады в схеме?
ответ
Последовательная оценка
Таким образом, последовательное вычисление выражения не характерно для монады, но функций. С того момента, как вы напишете f (g x)
(Haskell) или (f (g x))
(Схема), вы определили g
, как это происходит до f
. В Haskell мы вместо этого делаем это с операторами секвенирования, такими как (then f g)
и (bind f (lambda (x) (make-g x)))
, но вы можете сделать это, как хотите.
Путаница: монады имеют общую нотацию в Haskell по крайней мере, и эта общая нотация ставит утверждения в императивном порядке. С точки зрения схемы это макрос do
, который переписывает:
(do
(put-string "Hey, what's your name?")
(into x get-line)
(put-string (string-append "Hi, " x "!")))
в
(then
(put-string "Hey, what's your name?")
(bind get-line (lambda (x)
(put-string (string-append "Hi, " x "!")))))
Обратите внимание, что лямбды получить «сглаженный» и заменить каким-то новым символом «в». (На самом деле в Haskell мы бы сказали, «от», но это оператор инфикса, а не оператор префикса.)
Что монады
Так что является монадой, на самом деле? Ну, во-первых, давайте определим их часть речи: монады - это прилагательные, как прилагательное «синий». У меня может быть синий вагон или синее колесо. Monads functors, что означает, что с учетом функции от вагонов до их колес я могу дать вам функции от синий вагоны к их синий колеса. Таким образом, функции могут «работать под ними». Но монады имеют два специальных свойства. Сначала у нас есть идея, которая применима только к «синим», если мы сделаем идею необычно абстрактной и метафизической.: прилагательное должно быть , которое может быть применено к любому значению на этом языке. Таким образом, у вас есть не только синие вагоны и синие колеса, но и синие функции, синие программы, которые печатают «Hello, World!». на экран, все синее. Второй из прилагательного должен быть конденсируемым в том смысле, что данный синий синий вагон, вы можете просто дать мне синий вагон.
Одно прилагательное, которое делает это «обнуляемым ...». Вы всегда можете взять любое значение и создать на нем новое значение с нулевым значением: просто начните принимать и обнаруживать нулевые значения! Если вы находитесь на статически типизированном языке, где по умолчанию значения по умолчанию не равны нулю, это важно. Это прилагательное является функтором: при задании функции мы просто преобразуем null в нуль и все, что мы преобразуем с помощью функции. Это конденсируемо, потому что, если у нас есть «нулевая нулевая строка», которая сводится к нулевой строке: возьмите значения «null» и «not-null null» в «null» и «not-null not-null string» на «null», not-null string ". Наконец, чтобы представить любую строку как нулевую строку, преобразуйте ее в «непустую строку».Это называется монадой Maybe
. Это на самом деле специализированный случай монады Either y
, который может содержать y
.
Другое прилагательное, которое делает это «список ...». Чтобы применить функцию под прилагательным, примените ее ко всем членам списка. Чтобы сконденсировать список списков в список, объедините его элементы. Чтобы создать список x
из любого x
, верните мне список из одного элемента. Это называется «монадой списка». Написание этого способа очень похоже на понимание списков списков, и на самом деле оно изоморфно Clojure-преобразователям, поэтому вы получаете бесплатно фильтры &.
Другое прилагательное, которое делает это «функцией от s до s и a ...». Чтобы создать один из них из любого x
, просто соедините входящее состояние с x
. Чтобы применить функцию, просто примените ее к соответствующей стороне выходной пары. Очень просто. Наконец, если у вас есть свернутая ситуация s -> (s, s -> (s, a))
, постройте s -> (s, a)
, подав входящие s на свернутую функцию, взяв s, который выходит из этого, и подает его на s -> (s, a)
, который выходит из него. Это даст вам (s, a)
, который вам нужно вернуть. Это называется «Монастырь State s
», потому что вы можете представить «s» как типизированное состояние.
Другое прилагательное, которое делает это «программа, которая возвращает». Если у вас есть int, мы можем построить программу, которая ничего не делает и возвращает int. Если у вас есть программа, которая возвращает int и функцию от ints к чему-то еще, мы можем сделать программу, а затем применить функцию к выходу программы. Наконец, если у вас есть «программа, которая возвращает программу, которая возвращает int», просто создайте программу, которая запускает внешнюю программу для вычисления внутренней, а затем запускает внутреннюю. Это называется монадой IO x
. (Аналогично обещаниям: обещанный обещанный x мало чем отличается от обещанного x.)
Вы можете видеть, что это очень широкий шаблон, и он не всегда четко подразумевает «последовательность».
Сравнивая схемы с Haskell
После того, как вы понимаете, что Haskell описывает все свои операции ввода/вывода, содержащий программы в качестве значений, а затем объединить их вместе, вы понимаете, что в основном мы делаем функционал I/O, став макроязык. Язык макросов не делает любой I/O сам по себе, но вы используете его для создания программ, которые делают для вас ввод/вывод. Вы кормите их в компилятор, а компилятор создает фактическую программу, которая делает то, что вы хотите. Интерпретаторы получают немного более рискованно, потому что интерпретатор должен сказать «если я вижу значение, которое не является программой, я попытаюсь напечатать это, если я вижу значение, которое - это, программа, я попытаюсь запустить эту программу и затем распечатайте это ». Это означает, что синтаксис в командной строке тонко отличается от синтаксиса в файле.
Как только вы понимаете, что Haskell является средой метапрограммирования, в которой мы строим программу как ценность, вы поймете, как Haskell выполняет функциональные операции ввода-вывода, и вы увидите программируемый синтаксис для «monads» as мета-метапрограммирование. Этот дизайн гораздо менее сложный, чем макросы (которые мы также имеем в Haskell, это называется «Template Haskell»), но выполняет работу для множества полезных случаев. И по существу, о перегрузке на каком-то уровне, что «a; b; c; d» означает быть зависимым от (общего) внешнего прилагательного типов a, b, c и d. Для ввода/вывода это означает «сделать a, затем сделать b, затем ...»; для состояний это означает «поток состояния, созданного а в b, тогда состояние, созданное b в c, затем ...»; для nullables это означает «сделать a, если это не является нулевым, использовать его для b, если это не пустое использование для выполнения c ...».Для списков это декартово произведение составляющих списков, «соберите все по всем путям».
- 1. Объяснение выражения лямбда в схеме
- 2. Вложенные Лямбда в схеме?
- 3. Устранить лямбда в схеме?
- 4. Вложенный лямбда в схеме
- 5. выражение Карта + лямбда в схеме
- 6. если заявление в лямбда-схеме
- 7. Выбор из лямбда-выражения с лямбда-выражения
- 8. Пытаясь понять это лямбда-выражение в схеме
- 9. как напечатать лямбда-выражения
- 10. Как использовать foldr и лямбда в схеме?
- 11. лямбда-выражения
- 12. как пошагово лямбда-выражения
- 13. лямбда-выражения в ToDictionary
- 14. лямбда-выражения в @ Html.DisplayNameFor()
- 15. Лямбда-выражения в Python
- 16. Использование переменных let в схеме лямбда в схеме
- 17. лямбда-выражения в vb.net
- 18. лямбда-выражения в Котлин
- 19. Лямбда-выражения в глубину
- 20. Лямбда-выражения в Java8
- 21. лямбда-выражения в PEG.js
- 22. Реализация лямбда-заявления на схеме?
- 23. Выражения регулярных выражений в схеме
- 24. Выражения запроса vs Лямбда-выражения
- 25. новообращенный впустили в лямбда в схеме
- 26. Как лямбда-выражения работают внутри?
- 27. Как использовать/понимать лямбда-выражения?
- 28. Как использовать || внутри выражения лямбда
- 29. В статье в лямбда-выражения
- 30. Как создать динамические выражения лямбда
Документы, которые вы читали, скорее всего, вводят в заблуждение. Монады - очень абстрактная идея, и, к сожалению, абстрактные идеи привлекают всевозможные непреднамеренные дезинформации. Я не хочу сам объяснять это и потенциально способствовать большей путанице (поэтому я не хочу писать полный ответ), поэтому я просто свяжу вас с хорошо расцененной статьей для создания интуиции о монадах: [«Вы могли бы придумать монады! (и, возможно, у вас уже есть.)»] (http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html) , –
Не совсем. Монады могут использоваться для немого секвенирования, но они больше о том, что происходит * между * каждой операцией, чем сама секвенция (они называются «программируемыми точками с запятой»). Однако статья @ Тихона - замечательная, и я определенно рекомендую ее. –