2016-11-19 10 views
3

AFAIK один из новых дополнений к GHC8 является расширение ApplicativeDo языка, который desugars сделайте обозначение для соответствующих Applicative методов (<$>, <*>), если это возможно. У меня есть следующие вопросы.ApplicativeDo в Haskell

Как это решить, возможно ли обессоливание до Applicative? Из того, что я знаю, он проверяет зависимость (если позже зависит от результата прежнего), чтобы принять решение о приемлемости. Существуют ли другие критерии?

Хотя это дополнение упрощает чтение аппликативного кода для классов, у которых нет экземпляра Monad (возможно?). Но для структур, у которых есть Монада и аппликативный пример: Является ли это рекомендуемой практикой (с точки зрения читаемости)? Есть ли другие преимущества?

ответ

8

Как это решить, возможно ли обессоливание до Applicative? Из того, что я знаю, он проверяет зависимость (если позже зависит от результата прежнего), чтобы принять решение о приемлемости. Существуют ли другие критерии?

paper и trac page являются лучшими источниками информации. Некоторые моменты:

  • ApplicativeDo использует аппликативные везде, где это возможно - в то числе смешивая их с >>= в некоторых случаях, когда только часть do блока является аппликативным
  • Своего рода ориентированного графа зависимостей строятся, чтобы увидеть, какие части могут быть "parallelized"
  • Иногда нет очевидного перевода этого графа! В этом случае, GHC выбирает вариант перевода, который (грубо говоря) локально маленький

Хотя это дополнение делает более удобным для чтения для классов, которые не имеют каких-либо Monad экземпляр аппликативны кода (может быть?). Но для структур, которые имеют как Monad, так и экземпляр Applicative: Является ли это рекомендуемой практикой (с точки зрения читаемости)? Есть ли другие преимущества?

Here is an answer о разнице между Applicative и Monad. Процитируем непосредственно:

Для развертывания <*>, вы выбираете два вычисления, одна из функций, другой из аргумента, то их значения объединяются с помощью приложения. Чтобы развернуть >>=, вы выбираете одно вычисление, и вы объясните, как вы будете использовать его результирующие значения, чтобы выбрать следующее вычисление. Это разница между «пакетным режимом» и «интерактивной» операцией.

Ярким примером такого рода вещи является Haxl монада (разработанный Facebook), который все о получении данных от какого-либо внешнего источника. Используя Applicative, эти запросы могут происходить параллельно, а Monad заставляет запросы быть последовательными. Фактически, этот пример - это то, что побудило Саймона Марлоу в Facebook сделать расширение ApplicativeDo и написать цитированную статью об этом.

В целом, большинство случаев Monad не обязательно получают выгоду от Applicative. Из того же ответа я цитировал выше:

Я понимаю, что ApplicativeDo является отличным способом, чтобы сделать больше Аппликативный (а в некоторых случаях это означает быстрее) программу, которые были написаны в монадической стиле, что у вас есть не время рефакторинг. Но в противном случае я бы утверждал, что аппликативный-когда-ты-можешь-но-монадический-когда-ты-должен также лучший способ увидеть, что происходит.

Итак: использовать Applicative над Monad, когда это возможно, и использовать ApplicativeDo, когда это на самом деле лучше писать (как это должно быть в некоторых случаях на Facebook), чем соответствующий аппликативном выражения.