Kotlin 难以同时使用arrow、Option和RxJava
我很难找到一个很好的方法来协调使用RxJava和箭头ktKotlin 难以同时使用arrow、Option和RxJava,kotlin,functional-programming,reactive-programming,rx-java2,arrow-kt,Kotlin,Functional Programming,Reactive Programming,Rx Java2,Arrow Kt,我很难找到一个很好的方法来协调使用RxJava和箭头kt或者和选项类型。我有两种方法,既返回代码>单< P>,如果我是你,我会考虑简化你的返回类型,而不使用 >在单< /代码>中,因为单< /代码>已经可以发出错误。因此,最终,您只能使用选项,并处理RxJava链中的错误,而不是在或上进行平面映射。比如: class Foo(val qux: Option<Qux>) class Bar class Qux class ApiError fun loadFoo(): Single
或者和选项类型。我有两种方法,既返回代码>单< P>,如果我是你,我会考虑简化你的返回类型,而不使用<代码> <代码> >在<代码>单< /代码>中,因为<代码>单< /代码>已经可以发出错误。因此,最终,您只能使用选项
,并处理RxJava链中的错误,而不是在或
上进行平面映射。比如:
class Foo(val qux: Option<Qux>)
class Bar
class Qux
class ApiError
fun loadFoo(): Single<Option<Foo>> {
// in case of an error, this will return Single.error(ApiError(...)) if ApiError extends Throwable
// otherwise make it extend it or just wrap it into something which is a Throwable
}
fun loadBar(qux: Qux): Single<Option<Bar>> {
// same as above
}
fun loadBarFromFooOption(maybeFoo: Option<Foo>): Single<Option<Bar>> {
return maybeFoo.flatMap { foo -> foo.qux }
.map { qux -> loadBar(qux) }
.getOrElse { Single.just(Option.empty()) }
}
fun doStuffToGetBar(): Single<Option<Bar>> {
return loadFoo().flatMap { fooOption -> loadBarFromFooOption(fooOption) }
}
// somewhere else
doStuffToGetBar().subscribe({ barOption -> /* ... */ }, { error -> /* ... */ })
class-Foo(val-qux:Option)
分类栏
类群
类错误
fun loadFoo():单个{
//在发生错误的情况下,如果APIRROR扩展了Throwable,则将返回Single.error(APIRROR(…))
//否则,让它扩展它或只是把它包装成一个可以扔掉的东西
}
趣味加载条(qux:qux):单人{
//同上
}
趣味LoadBarFromFoooOption(maybeFoo:Option):单个{
返回maybeFoo.flatMap{foo->foo.qux}
.map{qux->loadBar(qux)}
.getOrElse{Single.just(Option.empty())}
}
fun doStuffToGetBar():单个{
返回loadFoo().flatMap{fooooption->loadBarFromFooOption(fooooption)}
}
//其他地方
doStuffToGetBar().subscribe({barOption->/*…*/},{error->/*…*/})
是的,这是一个关于单身汉已经能够发出错误的好观点。我认为我们的目标是使用其中一个。Left来清楚地定义所有预期的错误情况。然后,当我们订阅Observable时,如果不实现错误处理程序,它将使任何异常/意外错误崩溃。
fun loadBarFromMaybeFoo(maybeFoo: Option<Foo>): Single<Either<ApiError, Option<Bar>>> {
return maybeFoo.flatMap { foo -> foo.qux }
.map { qux -> loadBar(qux) }
.getOrElse { Single.just(Either.Right(Option.empty())) }
}
fun doStuffToGetBar(): Single<Either<ApiError, Option<Bar>>> {
return loadFoo()
.flatMap { maybeFooOrError ->
maybeFooOrError.fold(
{ error -> Single.just(Either.Left(error)) },
{ maybeFoo -> loadBarFromMaybeFoo(maybeFoo) }
)
}
}
fun doStuffToGetBar(): Single<Either<ApiError, Option<Bar>>> {
return SingleK.monadDefer().bindingCatch {
val maybeFooOrError: Either<ApiError, Option<Foo>> = loadFoo().k().bind()
val maybeQuxOrError: Either<ApiError, Option<Qux>> = maybeFooOrError.map { maybeFoo ->
maybeFoo.flatMap { it.qux }
}
// return type is Either<ApiError, Option<Either<ApiError, Option<Bar>>>>
// desired return type is Either<ApiError, Option<Bar>>
maybeQuxOrError.map { maybeQux ->
maybeQux.map { qux ->
loadBar(qux).k().bind() // this part doesn't seem good
}
}
}.value()
}
class Foo(val qux: Option<Qux>)
class Bar
class Qux
class ApiError
fun loadFoo(): Single<Option<Foo>> {
// in case of an error, this will return Single.error(ApiError(...)) if ApiError extends Throwable
// otherwise make it extend it or just wrap it into something which is a Throwable
}
fun loadBar(qux: Qux): Single<Option<Bar>> {
// same as above
}
fun loadBarFromFooOption(maybeFoo: Option<Foo>): Single<Option<Bar>> {
return maybeFoo.flatMap { foo -> foo.qux }
.map { qux -> loadBar(qux) }
.getOrElse { Single.just(Option.empty()) }
}
fun doStuffToGetBar(): Single<Option<Bar>> {
return loadFoo().flatMap { fooOption -> loadBarFromFooOption(fooOption) }
}
// somewhere else
doStuffToGetBar().subscribe({ barOption -> /* ... */ }, { error -> /* ... */ })