Это может помочь рассмотреть, относительно do
самой записи, для чего она на самом деле хороша.Как указывает Трэвис Браун, я ранее выступал за использование стиля «функционального приложения» с Monad
s и связанными типами, но есть и обратная сторона этого: Некоторые выражения просто не могут быть написанычисто в стиле приложения прямой функции .Например, следующее может быстро сделать аппликативный стиль неуклюжим:
- Промежуточные результаты, используемые в нескольких подвыражениях, на разной глубине вложения
- Аргументы самой внешней функции, используемой глубоко вложенными в подвыражениях
- Неуклюжий или непоследовательный порядок аргументов, т. Е. Необходимость частичного применения функции к чему-либо, кроме ее первого аргумента
- Глубоко встроенное управление потоком на основе промежуточных результатов с общими подвыражениями между ветвями
- Сопоставление с образцом для промежуточных результатов, особенно в случае извлечения части результата, использования его для дальнейших вычислений, а затем восстановления модифицированной версии в качестве следующего результата
Запись такой функции как одногоОбычно для выражения требуется либо несколько вложенных лямбд, либо абсурдная запутывающая бессмыслица, которая придает бессмысленному стилю плохое имя.Блок do
, с другой стороны, обеспечивает синтаксический сахар для удобного определения промежуточных результатов со встроенным потоком управления.
Обычно вы, вероятно, извлекаете такие подвыражения и помещаете их в предложение where
или что-то в этом роде, но поскольку обычные значения образуют монаду с применением функции в виде (>>=)
, а именно - Identity
монада--вместо этого вы могли бы написать такую функцию в блоке do
, хотя люди могут смотреть на вас забавно.
Помимо области видимости / привязки, другая вещь, которую блок do
делает для васЭлида оператор, который объединяет подвыражения вместе.Нетрудно представить другие случаи, когда было бы неплохо иметь нотацию для «объединения этих выражений с использованием этой функции в этом блоке», а затем позволить компилятору заполнить пробелы.
В простом случаегде выражения имеют один и тот же тип, размещение их в списке и последующее свертывание хорошо работает - строение строк выполняется таким образом, например, с использованием unwords
и unlines
.Преимущество do
состоит в том, что он объединяет выражения с общей структурой и совместимыми, но не идентичными типами.
Фактически, тот же общий принцип справедлив для обозначения «идиома» из бумаги Applicative
: где в блоках do
используются символы новой строки, чтобы исключить монадическую конструкцию, в скобках идиомы используется сопоставление, чтобы исключить применение функции с поднятыми функциями.,Нотация proc
для Arrow
также аналогична, и другие понятия также могут быть четко выражены таким образом, например:
- Составление структур данных, например, слияние наборов результатов некоторого вида,исключение функции слияния
- Другие идиомы приложения функции, такие как стиль "прямой канал" в первом аргументе, исключение оператора приложения
- Параллельные вычисления, исключение функции агрегации результата
Хотя не так уж и сложно превратить многие из них в один тип или полный экземпляр Monad
, было бы неплохо иметь единый расширяемый кусочек синтаксического сахара для общей концепции.Конечно, есть общий поток, связывающий все это и многое другое, но это гораздо более обширная тема, не связанная с синтаксисом ...