如何将Either.Right转移到Either.Left?
How to transfer Either.Right to 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
))
如果第一个测试没有通过,它将return Either.Left,第二个不会被调用。它将输出:
_Right {value: user}
但是如果第一个通过而第二个没有通过,那么就会变成:
_Right {value: _Left {value: err}}
我要它只输出_Left {value: err},请问如何修改代码或者有什么方法可以将右移到左?
您注意到 map
无法 "flatten" 两个 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)
));
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
))
如果第一个测试没有通过,它将return Either.Left,第二个不会被调用。它将输出:
_Right {value: user}
但是如果第一个通过而第二个没有通过,那么就会变成:
_Right {value: _Left {value: err}}
我要它只输出_Left {value: err},请问如何修改代码或者有什么方法可以将右移到左?
您注意到 map
无法 "flatten" 两个 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)
));