Как перевести Either.Right на Either.Left?
db.findUser(id).then(R.pipe(
R.ifElse(firstTestHere, Either.Right, () => Either.Left(err)),
R.map(R.ifElse(secondTestHere, obj => obj, () => Either.Left(err))),
console.log
))
Если первый тест не пройдет, он вернет Either.Left, а второй не будет вызван. Это будет положить:
_Right {value: user}
Но если первый пройден, а второй нет, он станет:
_Right {value: _Left {value: err}}
Я хочу, чтобы он выводил только _Left {value: err}, как исправить код или есть какой-нибудь способ передачи справа налево?
1 ответ
Вы заметили, что map
не может "сгладить" два Either
экземпляры вместе. Для этого вы захотите использовать chain
вместо.
db.findUser(id).then(R.pipe(
R.ifElse(firstTestHere, Either.Right, () => Either.Left(err)),
R.chain(R.ifElse(secondTestHere, Either.Right, () => Either.Left(err))),
console.log
))
Эта схема составления серии вызовов для объединения в цепочку также может быть достигнута с помощью composeK
/ pipeK
где каждая функция, которая должна быть составлена, должна иметь вид Monad m => a -> m b
функция, которая производит некоторую монаду (такую как Either
) от заданного значения.
С помощью R.pipeK
Ваш пример может быть изменен на что-то вроде:
// helper function to wrap up the `ifElse` logic
const assertThat = (predicate, error) =>
R.ifElse(predicate, Either.Right, _ => Either.Left(error))
const result = db.findUser(id).then(R.pipeK(
assertThat(firstTestHere, err),
assertThat(secondTestHere, err)
));