Haskell: Будет ли нотация «делать» полезна для контекстов, отличных от монад? - PullRequest
10 голосов
/ 26 июля 2010

Мы все любим do, и мне было любопытно, возможно, такой альтернативный синтаксис теоретически будет полезен за пределами мира монад. Если да, то какие еще виды вычислений это упростит? Имеет ли смысл иметь что-то эквивалентное для Applicative, например?

Ответы [ 8 ]

13 голосов
/ 26 июля 2010

Я чувствую, что многие программисты на Haskell вообще не любят do, и это один из распространенных аргументов в пользу использования Applicative, когда вам не нужны все возможности Monad заключается в том, что комбинаторы <$>, <*> и т. Д. Допускают очень ясный и лаконичный стиль кодирования.

Даже для монадического кода многие люди предпочитают использовать =<< явно вместо do обозначения, camccann ответ на ваш предыдущий вопрос о <*> дает фантастический аргумент в пользу этого предпочтения.

Я склонен писать свои первые проекты, используя do изатем заменить комбинаторами, как я пересмотреть.Это всего лишь мой собственный (не) опыт и вкус: мне часто легче набросать вещи более императивным образом (что более удобно с do), но я думаю, что не do кодобычно красивее.

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

9 голосов
/ 27 июля 2010

Это может помочь рассмотреть, относительно do самой записи, для чего она на самом деле хороша.Как указывает Трэвис Браун, я ранее выступал за использование стиля «функционального приложения» с Monad s и связанными типами, но есть и обратная сторона этого: Некоторые выражения просто не могут быть написанычисто в стиле приложения прямой функции .Например, следующее может быстро сделать аппликативный стиль неуклюжим:

  • Промежуточные результаты, используемые в нескольких подвыражениях, на разной глубине вложения
  • Аргументы самой внешней функции, используемой глубоко вложенными в подвыражениях
  • Неуклюжий или непоследовательный порядок аргументов, т. Е. Необходимость частичного применения функции к чему-либо, кроме ее первого аргумента
  • Глубоко встроенное управление потоком на основе промежуточных результатов с общими подвыражениями между ветвями
  • Сопоставление с образцом для промежуточных результатов, особенно в случае извлечения части результата, использования его для дальнейших вычислений, а затем восстановления модифицированной версии в качестве следующего результата

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

Обычно вы, вероятно, извлекаете такие подвыражения и помещаете их в предложение where или что-то в этом роде, но поскольку обычные значения образуют монаду с применением функции в виде (>>=), а именно - Identity монада--вместо этого вы могли бы написать такую ​​функцию в блоке do, хотя люди могут смотреть на вас забавно.


Помимо области видимости / привязки, другая вещь, которую блок do делает для васЭлида оператор, который объединяет подвыражения вместе.Нетрудно представить другие случаи, когда было бы неплохо иметь нотацию для «объединения этих выражений с использованием этой функции в этом блоке», а затем позволить компилятору заполнить пробелы.

В простом случаегде выражения имеют один и тот же тип, размещение их в списке и последующее свертывание хорошо работает - строение строк выполняется таким образом, например, с использованием unwords и unlines.Преимущество do состоит в том, что он объединяет выражения с общей структурой и совместимыми, но не идентичными типами.

Фактически, тот же общий принцип справедлив для обозначения «идиома» из бумаги Applicative: где в блоках do используются символы новой строки, чтобы исключить монадическую конструкцию, в скобках идиомы используется сопоставление, чтобы исключить применение функции с поднятыми функциями.,Нотация proc для Arrow также аналогична, и другие понятия также могут быть четко выражены таким образом, например:

  • Составление структур данных, например, слияние наборов результатов некоторого вида,исключение функции слияния
  • Другие идиомы приложения функции, такие как стиль "прямой канал" в первом аргументе, исключение оператора приложения
  • Параллельные вычисления, исключение функции агрегации результата

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

7 голосов
/ 26 июля 2010

Обозначение do - это, по сути, способ сказать «превращайтесь в лямбды по мере необходимости и распределить >>= между строк ".

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

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

  • Начало do.
  • Между do с.
  • Конец do.

Тогда вам, вероятно, больше не следует называть это do. Может быть, это просто скобка.

5 голосов
/ 27 июля 2010

Идиоматические скобки образуют хороший способ думать о Applicative, но они не единственно возможное такое расширение синтаксиса.

Philippa Cowderoy опубликовал предложение для «Applicative do» Некоторое время назад в haskell-cafe было замечено, что любая функция, которая выглядит примерно так:

foo = do
    x <- bar
    y <- baz
    quux y 1234 x

, где переменные, связанные с <-, встречаются только в последней строке, могут быть реализованы с Applicative -Я фактически реализовал макрос на основе правила синтаксиса для этого в схеме, которую я назвал «ado».

Это полезно в тех случаях, когда порядок аппликативных эффектов отличается от «естественного порядка» и предполагает существованиеиз 'ado' в Haskell будет просто десагар:

foo = (\x y -> quux y 1234 x) <*> bar <*> baz

Однако, лексические правила определения области действия немного сбивают с толку.

3 голосов
/ 27 июля 2010

BlazeHtml использует примечание do, когда на самом деле это просто Monoid (хотя оно может быть заключено в Monad для возможности использования do).

Тактам была бы полезна аналогичная запись для Monoid s.

Если вы посмотрите на код моей игры "Защити короля" , то я также сделаю много mconcatи, как и BlazeHtml, я бы получил от этого приятный синтаксис.

3 голосов
/ 26 июля 2010

Applicative имеет (гораздо более ограниченные и более компактные) идиомные скобки, см. Аппликативное программирование с эффектами , стр. 4. Я думаю, что в среде Контра Макбрайда Стратклайда Хаскелла реализованы эти условия.

Я не понимаю, как обобщить эти виды специальных синтаксисов, но, возможно, я недостаточно обдумал это.

2 голосов
/ 27 июля 2010

Существует обобщение монад, которое соответствует обозначению do - параметризованные монады. См. За пределами Монад от sigfpe. Пример использования:

test1' = do put 1
            x <- get
            put (show x)
            y <- get
            return (x,y)

Это «монада состояний», в которой сначала хранится число, а затем строка.

1 голос
/ 26 июля 2010

В GHC есть препроцессор, который делает это только для стрелок: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/arrow-notation.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...