0
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
))

If the first test doesn't pass, it will return Either.Left, and the second one won't be called. It will out put:

_Right {value: user}

But if the first one passed but the second one doesn't, it will become:

_Right {value: _Left {value: err}}

I want it to output _Left {value: err} only, how to fix the code or is there any way to transfer the Right to the Left?

4

1 回答 1

2

您注意到的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产生一些 monad(例如)的函数。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)
));
于 2017-05-20T07:00:36.257 回答