Автор оригинала: FreeCodeCamp Community Member.
Раджараодомв
Функциональное программирование (FP) может изменить то, как вы программируете для лучшего. Но трудно учиться, и многие посты и учебные пособия не входят в подробности, такие как монады, применение и так далее, и, похоже, не используют практические примеры, чтобы помочь нам ежедневно использовать мощные методы FP на ежедневной основе. Вот почему я думал о написании поста, чтобы облегчить использование методов FP.
В части 1 вы изучите функциональные основы программирования, карри, чистых функций, «Фэнтези-земельные» спецификации «Фэнтези-земельные», «Функторы», «Монады», «Может быть, монады» и «Монады» через пару примеров.
Функциональное программирование
Функциональное программирование – это стиль написания программ, просто составив набор функций.
По сути, FP просит нас обернуть практически все в функциях, написать много небольших многоразовых функций и просто позвоните им один за другим, чтобы получить результат, такой как: ( func1.func2.func3 ) или в моде составляющих, как: func1 (func2 (func3 ())) Отказ
Но для того, чтобы на самом деле написать программы в этом стиле, функции должны следовать за некоторыми правилами и преодолеть некоторые проблемы, как указанные ниже:
Проблемы FP:
Если все можно сделать, составление набора функций.
- Как мы можем справиться с этим условием? ( Подсказка: «Либо« Монад )
- Как мы можем обрабатывать нулевые исключения ( подсказка: «Может быть,« Монад )?
- Как гарантировать, что функции действительно «многоразовые» и могут быть повторно использованы в любом месте, ( Подсказка: Чистые функции, Референтная прозрачность )?
- Как гарантировать, что данные, которые мы передаем к нему без изменений, чтобы мы могли повторно использовать данные в другом месте ( Подсказка: Чистые функции, неизменность )?
- Если функция принимает несколько значений, но цепочка может передавать только одно значение, как мы можем до сих пор сделать его частью цепочки ( Подсказка: « Carrying» и «Функции высшего порядка» )?
- И еще .. <Добавьте свой вопрос здесь>.
Решение FP:
Чтобы справиться со всеми этими проблемами, полностью функциональные языки программирования, такие как Haskell, предоставляют различные инструменты и концепции математики, такие как «монады», «Функторы» и так далее.
В то время как JavaScript не предоставляет многие из коробку инструментов, к счастью, у него достаточно функций FP, которые позволяют людям писать библиотеки.
Фэнтези-земельные характеристики и библиотеки FP
Библиотеки, которые хотят предоставить функции, такие как функторы, монады и так далее, необходимы для реализации функций/классов, которые следуют на некоторых спецификациях, чтобы предоставить функциональные возможности, такие как они находятся на языках, таких как Haskell.
Фантасиландные спецификации является одним из выдающихся спецификаций, которые объясняют, как каждая функция/классы JS должны вести себя.
Вышеуказанное изображение показывает все спецификации и их зависимости. Спецификации по сути являются законами и похожи на «интерфейсы» в Java. С точки зрения JS, вы можете подумать о спецификациях как функциях «классов» или конструктора, которые реализуют некоторые методы, такие как ( Map , , цепочка и т. Д.) Согласно спецификации.
Например:
Класс JS – это «функтор», если он реализует метод «карта». И этот способ MAP должен работать в соответствии с SPEC (PS: это упрощенная версия, и есть больше правил).
Точно так же класс JS – это «применить функтор», если он реализует функции «карты» и «AP» в соответствии с спецификацией.
Точно так же класс JS является «монадом» (AKA Monad Fanctor), если реализует требования «функтора», «применять», «применитель», «цепь» и «сама« монад »(из-за цепочки зависимости).
Fantasy-Land Spec Соответствующие библиотеки
Есть несколько библиотек, которые реализуют FL SPEC. Например: monet.js, едва функционально , Фольктейлейс , Рамда-фантазия (на основе Ramda), Immutable-Ext (на основе immutablejs), Плотмую и больше.
Какие библиотеки я должен использовать?
Библиотеки, как lodash-fp , Ramdajs , только позволяют вам начать писать в стиле FP. Но они не предоставляют функции для использования ключевых математических концепций, таких как монады, функторы, складываясь, чтобы фактически решать реальные проблемы.
Итак, в дополнение к ним вам придется использовать одну из библиотек, которые следуют спецификации Fantasy-Land. Некоторые такие библиотеки: monet.js, едва функционально, Фольктейлейс , Рамда-фантазия (на основе Ramda), Immutable-Ext (на основе immutablejs), Плотмую и больше.
Хорошо, теперь, когда мы знаем основы, давайте посмотрим некоторые практические примеры и изучаем различные функции и методики FP через эти примеры.
Пример 1 – Работа с нулевыми чеками
Темы покрыты: функторы, монады, может быть, монад, карри.
Корпус использования: Мы хотим показать другую веб-страницу индекса в зависимости от пользователя « Primary» Язык (Внутри префодации пользователя см. Ниже). И нам нужно написать geturlforuser который возвращает подходящую URL Из списка URL ( indexurls ) для пользователя ( joeuser ) Первичный Язык (« Испанский» ).
Проблема в том: Первичный язык может быть нулевым. Сам пользователь может быть нулевым (не вошедшим в систему). Первичный язык может быть не доступен в нашем списке indenturls. Поэтому нам придется позаботиться о многих «нулевых» или «неопределенных».
Решение (императив против ФП):
Хорошо, давайте сначала понять несколько концепций FP и методики, используемые в этом решении.
Функторы
Любой класс (или функция строительства) или тип данных, который хранит значение и реализацию «карта», называется «функтором».
Например: массив – это «функтор». Поскольку массив может хранить значения и имеет метод «Карта», который позволяет нам отображать функцию значений, которые он хранится.
const add1 = (a) => a+1;
let myArray = new Array(1, 2, 3, 4); //store values
myArray.map(add1) // -> [2,3,4,5] //applies functions
Давайте напишем нашем собственном функторе «MyBuntor». Это просто класс JS (функция конструктора), которая хранит некоторое значение и реализует метод «карта». Этот метод «MAP» применяет функцию в сохраненное значение, а затем создает новый MyBunctor из результата и возвращает этот новый myfunctor.
Монад
Монады также являются функторами, то есть у них есть « Map » метод, но реализует больше методов, чем просто «карта». Если вы снова посмотрите на график зависимости спецификации, вы увидите, что также нужно реализовать различные другие функции в разных спецификациях: « Применить » ( AP Метод), « Применитель » ( AP и Метод), а ” цепочка ” ( цепочка метод).
Упрощенное объяснение: В JS Monads – это классы или конструкторские функции, которые хранят некоторые данные и реализуют «карту», «AP», «из» и «цепочки», которые делают что-то с сохраненными данными в соответствии с спецификацией.
Ниже приведен образец реализации, чтобы получить представление о внутренних органах монады.
Теперь общие монады обычно не используются, но более конкретные и более полезные монады, такие как «может быть, монад» или «либо монад», часто используются в программировании FP. Итак, давайте посмотрим на «Монаде».
«Может быть,« Монад
А «Может, Монад – это класс, который реализует монаду спецификации. Но особые вещи о монаде состоит в том, что это заботится о «нулевых» или «неопределенных» значениях.
В частности, если хранимые данные являются NULL или undefined, то это функция «карта» не запускает заданную функцию вообще и там, избегая никаких нулей или неопределенных проблем Отказ Он используется в ситуациях, когда мы имеем дело с нулевыми значениями.
Давайте посмотрим, как использовать, может быть, монад, чтобы иметь дело с проверками «NULL».
Следуй этим шагам:
- Если есть любой объект, который может быть нулевым или иметь нулевые свойства, создайте из него объект монады.
- Используйте некоторые библиотеки, такие как Ramdajs, которые являются «может быть в курсе» для доступа к стоимости от W/Monad и работают над ним.
- Укажите значение по умолчанию, если фактическое значение происходит для NULL (I.E обрабатывающая нулевые ошибки APPRONT).
Carrying – (помогает справиться с глобальными данными и многоэтажными функциями)
Темы покрыты: Чистые функции и Состав
Если мы хотим цепи серию функций, таких как: func1.func2.func3 или (func1 (func2 (func3 ())), все эти функции могут получать только один входной параметр каждый. Например, если func2 принимает два параметра Func2 (param1, param2), то мы не можем цеплять!
Но практически говоря, многие функции принимают несколько параметров. Так как их использовать в композиции? Решение: «Карри».
Carrying преобразует функцию, которая принимает несколько параметров в функцию, которая принимает один параметр за раз. Это не запускает функцию, пока все параметры не будут переданы.
Кроме того, Carrying также можно использовать в ситуациях, когда мы получаем доступ к глобальным значениям. И.Е. Сделайте это «чистым».
Давайте снова посмотрим на наше решение:
Пример 2- Обработка ошибок, бросающих функции и выходов сразу после ошибки
Темы покрыты: «Либо монад»
Возможно, Монад отлично, если у нас есть значения «по умолчанию», чтобы заменить нулевые ошибки. Но как насчет функций, которые на самом деле нужно бросать ошибки? И как узнать, какая функция бросила ошибку при цепочке нескольких функций бросаний по ошибкам (то есть мы хотим быстро сбой)?
Например: если у нас есть func1.func2.func3 … и если Func2 бросил ошибку, мы должны пропустить Func3 и другие будущие функции и правильно показать ошибку от Func2 Таким образом, мы можем справиться с этим.
Либо монад
Либо монады отлично подходят для устранения нескольких функций, когда все они могут потенциально бросать ошибку и хотеть выйти сразу после ошибки, чтобы мы могли определить точку, где произошла ошибка.
Используйте корпус: Например, на нижнем огромном фрагменте мы рассчитываем ” налог ” и ” скидка ” за Предметы И в конечном итоге отображение ShowtotalPrice Отказ
Обратите внимание, что функция « налог » будет бросать ошибку, если цена не числовая. Точно так же, « Discount » функция бросает ошибку, если цена не числовой, и она также будет бросать ошибку, если цена товара составляет менее 10.
Давайте посмотрим, как ShowtotalPrice Может быть улучшен с помощью монады и переписать все в стиле FP.
Либо Монад предоставляет два конструкторов: «Толфть», так и «в одном». Думать о них как о подклассах либо. И «слева» и «правильные» являются монадами! Идея состоит в том, чтобы хранить ошибки/исключения в левых и полезных значениях вправо Отказ
I.e. Создайте экземпляр в зависимости от значения или в зависимости от значения. После того, как мы сделаем это, мы можем запустить карту, цепочку и так далее на этих ценностях, чтобы составить их.
Хорошо, давайте посмотрим, как изменить наш императивный пример на FP
Шаг 1: Оберните возвратные значения с левой и правой
Шаг 2: Оберните начальное значение в Правильно Потому что это допустимое значение, и поэтому мы можем сочинить его.
const getItemPrice = (item) => Right(item.price);
Шаг 3: Создайте две функции, один для обработки возможной ошибки и другой, чтобы обрабатывать результат. И деформируйте их в Или либо (Это из Ramda-Fantasy.js API ).
const displayTotal = (total) => { console.log('Total Price: ' + total) };
const logError = (error) => { console.log('Error: ' + error.message); };
const eitherLogOrShow = Either.either(logError, displayTotal);
Шаг 4: Используйте метод « цепь », чтобы составить несколько функций бросания по ошибкам. Передайте их результат к либо (в одном случае), который позаботится о передаче результата к обработчику успеха или обработчика отказов.
const showTotalPrice = (item) => eitherLogOrShow(getItemPrice(item).chain(apply25PercDisc).chain(addCaliTax));
Положить все это вместе:
Спасибо за чтение! Если вам понравилось сообщение, пожалуйста? И поделиться этим в Twitter! ??
Последнее: Функциональное программирование в JS – с практическими примерами (часть 2)
Мои другие посты
Функциональное программирование
- JavaScript Turing Complete – объяснил
- Функциональное программирование в JS – с практическими примерами (часть 1)
- Функциональное программирование в JS – с практическими примерами (часть 2)
ES6
WebPack
- WebPack – запутанные детали
- Замена WebPack & Hot модуль [HMR] (под капотом)
- HMR и React-Loader WebPack – отсутствующее руководство
Проект.js.
- Почему chank.js и почему вы должны внести свой вклад
- Как проект.js представляет богатые текстовые данные
Реагировать и redux:
- Шаг за шагом Руководство по созданию приложений React Redux
- Руководство для построения приложения React Redux Crud (3-страничное приложение)
- Использование Addractwares в React Redux Apps
- Добавление прочной проверки формы для реагирования приложений Redux
- Обеспечение приложений React Redux с токенами JWT
- Обработка транзакционных электронных писем в Action Redux Apps
- Анатомия приложения React Redux