Составление обещания и кастомная монада - PullRequest
0 голосов
/ 16 февраля 2019

Контекст

Я пытаюсь понять проблему, которую пытаются решить монады, и я немного растерялся, пытаясь составить контейнер и обещание.

Пример

Для целей упражнения я изменил метод моей монады chain на then, чтобы я мог составлять обещания с помощью своего пользовательского контейнера.:

const assert = require("assert");
const R = require("ramda");

const makeMonad = value => ({
  get: () => value,
  map: transform => makeMonad(transform(value)),
  then: createMonad => makeMonad(createMonad(value).get())
});

const asyncAdd2 = x => Promise.resolve(x + 2);

const composeP = R.composeWith((f, last) => last.then(f));
const asyncResult = composeP([asyncAdd2, makeMonad])(1);

asyncResult.then(x => assert.equal(x, 3));
console.log("Passed");

В этом примере выдается ошибка, поскольку API Promise не обладает функцией get.Фактически, мне нужна эта функция get в моей пользовательской функции then для обеспечения возможности компоновки.

Так что в конце выполнения приложения, в зависимости от порядка моих аргументов в вызове composeWith,Я нахожусь в мире обещаний или в обычном мире монад.

Вопросы

  • Теперь мне интересно, придется ли мне все поднимать (даже обещания?) Пока я работаю и пытаюсь сочинять монады?

  • Какое влияние окажет работа с 10 видами различных монад?Я имею в виду, в зависимости от порядка, я, вероятно, изменю мир, над которым я работаю, нет?

  • Это что-то общее для создания создателей монад?Я имею в виду создание определения монады наподобие makeMonad, которое я написал

Спасибо за вашу помощь, надеюсь, я был ясен ^^ '

1 Ответ

0 голосов
/ 22 мая 2019

Я пытаюсь понять проблему, которую пытаются решить монады

Возможно, вам будет полезно взглянуть на примеры и ссылки в этом репо https://github.com/dmitriz/functional-examples

Я немного растерялся, пытаясь составить контейнер и обещание.

Полагаю, вы знаете, что Обещание - это не Монада .

Для целей упражнения я изменил метод цепочки моей монады на then, чтобы я мог составлять обещания с помощью своего пользовательского контейнера

Какthen метод нарушает монадический закон , он не подходит для безопасной композиции.По сути, каждый раз, когда вы сочиняете с помощью функции, вы должны тщательно проверять все возможные возвращаемые значения на предмет того, были ли они обещаниями или нет, и убедиться, что композиция всегда развернута правильно.Который в основном побеждает точку Монады, которая позволяет вам безопасно составлять, не тратя время на проверку деталей.Если ваша цель - использовать Monads, вы можете вместо этого переключиться с then на chain.

Великолепная библиотека, обеспечивающая безопасность FP в Promises: Creed


  • Теперь мне интересно, придется ли мне все поднимать (даже обещания?) пока я работаю и пытаюсь сочинять монады?

Возможно, вы захотите обернуть все обещания в creed, а затем использовать предоставленные монадические методы обычным способом.

  • Каково влияние, если я работаю с 10 видами различных монад?Я имею в виду, в зависимости от порядка, я, вероятно, изменит мир, над которым я работаю, нет?

Монадические законы предназначены для фиксированной монады, то есть они действуют только для фиксированнойреализация методов of и chain.Также chain ожидайте правильной подписи:

chain :: Monad m => m a ~> (a -> m b) -> m b

Расшифровано: если m - фиксированная монада, a и b - любые типы, метод цепочки требует, чтобы его аргумент был функциейтипа a → m b, с m равным той же монаде .

Другими словами

monad.chain(a => makeMonad(a))

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

Для безопасной работы с обещаниями всегда заключайте их в Creed, чтобы гарантировать, что используется та же самая монада, затем используйте только map и chain всякий раз, когда сочиняете и полагаетесь на монадические законы.Или используйте then на свой риск и не забывайте о деталях:)

  • Это что-то обычное для создания создателей монад?Я имею в виду создание определения монады, например, makeMonad, который я написал

Это будет работать, только если у вас есть фактическое значение для начала, см., Например, здесь: https://github.com/dmitriz/functional-examples/blob/master/examples/16-monad.js

Но одна из возможностей Монады - иметь дело со значениями, к которым вы не можете (или не хотите) обращаться напрямую, например с IO Monad.В этих случаях вы можете использовать только предоставленных операторов, чтобы создавать или не создавать Монаду.Это иллюстрирует проблему с собственными обещаниями JS - вы не можете превратить их в монаду без изменения их значений.Собственное обещание JS всегда будет пытаться распаковать «theneable», который поэтому не может быть сохранен как значение, что делает любую композицию в целом небезопасной.

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