выполнить задачу Fluture с помощью Sancuary Either

У меня есть такая трубка

const asyncFn = (x) => {
    return Future.tryP(() => Promise.resolve(x + ' str2'))
};

const pipeResult = S.pipe([
    x => S.Right(x + " str1"), // some validation function
    S.map(asyncFn),
])("X");

pipeResult.fork(console.error, console.log);

Я хочу выполнить асинхронную операцию в asyncFn. Проблема в том, когда у меняRight в качестве ввода я могу его форкнуть.

Когда я регистрирую pipeResult Я вижу это:

Right (tryP(() => Promise.resolve(x + ' str2')))

Как я могу это сделать?

1 ответ

Решение

Either a b а также Future a bоба способны выражать неудачу / успех. При работе с асинхронными вычислениями обычно лучше использоватьFuture a b скорее, чем Future a (Either b c). Более простой и плоский тип требует меньше карт:S.map (f) скорее, чем S.map (S.map (f)). Еще одно преимущество состоит в том, что значение ошибки всегда в одном и том же месте, тогда как сFuture a (Either b c) обе a а также b представляют собой неудачные вычисления.

Однако у нас может уже быть функция проверки, которая возвращает либо. Например:

//    validateEmail :: String -> Either String String
const validateEmail = s =>
  s.includes ('@') ? S.Right (S.trim (s)) : S.Left ('Invalid email address');

Если у нас есть значение fut типа Future String String, как нам проверить адрес электронной почты futможет содержать? Первое, что нужно попробовать, это всегдаS.map:

S.map (validateEmail) (fut) :: Future String (Either String String)

Было бы неплохо избежать этого вложения. Для этого нам сначала нужно определить функцию изEither a b к Future a b:

//    eitherToFuture :: Either a b -> Future a b
const eitherToFuture = S.either (Future.reject) (Future.resolve);

Теперь мы можем преобразовать функцию, возвращающую одно из двух, в функцию, возвращающую в будущем:

S.compose (eitherToFuture) (validateEmail) :: String -> Future String String

Давайте вернемся к нашему использованию S.map:

S.map (S.compose (eitherToFuture) (validateEmail)) (fut) :: Future String (Future String String)

У нас все еще есть вложенность, но теперь оба типа - внутренний и внешний. Future String _. Это означает, что мы можем заменитьS.map с S.chain чтобы не вводить гнездование:

S.chain (S.compose (eitherToFuture) (validateEmail)) (fut) :: Future String String
Другие вопросы по тегам