Каковы практические применения аппликативного стиля? - PullRequest
63 голосов
/ 18 августа 2011

Я программист Scala, сейчас изучаю Haskell.Легко найти примеры практического использования и примеры из реальной жизни для концепций ОО, таких как декораторы, шаблоны стратегий и т. Д. Эти книги заполнены.

Я пришел к выводу, что это как-то не так для функциональных понятий.Показательный пример: аппликативные .

Я изо всех сил пытаюсь найти практические случаи использования для аппликативов.Почти все учебники и книги, с которыми я сталкивался до сих пор, содержат примеры [] и Maybe.Я ожидал, что аппликативы будут более применимыми, учитывая все внимание, которое они получают в сообществе FP.

Мне кажется, я понимаю концептуальную основу аппликативных (возможно, я ошибаюсь), и я долго ждал своего момента просветления.Но, похоже, этого не происходит.Никогда во время программирования у меня не было момента, когда я с радостью кричал: «Эврика! Я могу использовать здесь аппликатив!»(за исключением еще раз, для [] и Maybe).

Может, кто-нибудь подскажет мне, как можно использовать аппликативы в повседневном программировании?Как мне начать определять шаблон?Спасибо!

Ответы [ 11 ]

1 голос
/ 14 марта 2013

Я описал пример практического использования аппликативного функтора в обсуждении, которое я цитирую ниже.

Обратите внимание, что примеры кода являются псевдокодом для моего гипотетического языка, который скрывает классы типов в концептуальномформа подтипа, поэтому, если вы видите вызов метода для apply, просто переведите его в модель класса вашего типа, например, <*> в Scalaz или Haskell.

Если мы пометим элементы массива или hashmapс помощью null или none для указания того, что их индекс или ключ действительны, но не имеют значения, Applicative позволяет без всяких шаблонов пропускать бесполезные элементы при применении операций к элементам, которые имеют значение.И что более важно, он может автоматически обрабатывать любую семантику Wrapped, которая априори неизвестна, то есть операции над T над Hashmap[Wrapped[T]] (любым на любом уровне композиции, например, Hashmap[Wrapped[Wrapped2[T]]], потому что аппликативное является составным, а монада - нет).

Я уже могу представить, как это облегчит мой код.Я могу сосредоточиться на семантике, а не на всей этой лжи, и моя семантика будет открыта под расширением Wrapped, тогда как весь ваш пример кода - нет.

Значительно, я забыл упомянуть до этогоВаши предыдущие примеры не эмулируют возвращаемое значение Applicative, которое будет List, а не Nullable, Option или Maybe.Так что даже мои попытки исправить ваши примеры не эмулировали Applicative.apply.

Помните, functionToApply является входом для Applicative.apply, поэтому контейнер сохраняет контроль.

list1.apply( list2.apply( ... listN.apply( List.lift(functionToApply) ) ... ) )

Эквивалентно.

list1.apply( list2.apply( ... listN.map(functionToApply) ... ) )

И мой предложенный синтаксический сахар, который компилятор переведет в вышеприведенное.

funcToApply(list1, list2, ... list N)

Полезно прочитать это интерактивное обсуждение , потому что я не могу скопировать все это здесь.Я ожидаю, что URL не будет нарушен, учитывая, кто является владельцем этого блога.Например, я процитирую дальнейшее обсуждение.

связь между потоком управления вне оператора и присваиванием, вероятно, нежелательна для большинства программистов

Applicative.apply предназначен для обобщения частичного применения функций к параметризованным типам (или универсальным) на любом уровне вложенности (композиции) параметра типа.Это все о создании более обобщенной композиции.Общность не может быть достигнута путем вытягивания ее за пределы завершенной оценки (т. Е. Возвращаемого значения) функции, аналогично тому, что лук не может быть очищен изнутри.

Таким образом, это не путаницаэто новая степень свободы, которая в настоящее время недоступна для вас.В нашем обсуждении, вот почему вы должны выбросить исключения или сохранить их в глобальной переменной, потому что ваш язык не имеет такой степени свободы.И это не единственное применение этих функторов теории категорий (изложено в моем комментарии в очереди модераторов).

Я предоставил ссылку на пример абстрагирования валидации в Scala, F # и C #, который в данный момент застрял в очереди модератора.Сравните отвратительную версию кода на C #.И причина в том, что C # не обобщен.Я интуитивно ожидаю, что шаблон для конкретного случая C # будет взрываться геометрически по мере роста программы.

...