Skip to content

Instantly share code, notes, and snippets.

@bejibx
Created September 25, 2019 21:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bejibx/9194bc511a2765db69bb8c665b3476c4 to your computer and use it in GitHub Desktop.
Save bejibx/9194bc511a2765db69bb8c665b3476c4 to your computer and use it in GitHub Desktop.
package com.bejibx.android.testdataprocessor
import arrow.core.Either
import arrow.fx.rx2.ForSingleK
import arrow.fx.rx2.SingleK
import arrow.fx.rx2.extensions.singlek.functor.functor
import arrow.fx.rx2.extensions.singlek.monad.monad
import arrow.fx.rx2.k
import arrow.fx.rx2.value
import arrow.mtl.EitherT
import arrow.mtl.EitherTOf
import arrow.mtl.EitherTPartialOf
import arrow.mtl.extensions.eithert.monad.monad
import arrow.mtl.value
import arrow.typeclasses.MonadSyntax
import io.reactivex.Single
import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable
class UseCaseA {
fun getSomething(): Single<Either<ErrorA, Int>> {
return Single.just(Either.left(ErrorA.Option1))
}
}
sealed class ErrorA {
object Option1 : ErrorA()
object Option2 : ErrorA()
}
class UseCaseB {
fun convertSomething(s: Int): Single<Either<ErrorB, String>> {
return Single.just(Either.left(ErrorB.Option1))
}
}
sealed class ErrorB {
object Option1 : ErrorB()
object Option2 : ErrorB()
}
sealed class ErrorAB {
object Option1 : ErrorAB()
object Option2 : ErrorAB()
object Option3 : ErrorAB()
object Option4 : ErrorAB()
companion object {
fun from(error: ErrorA): ErrorAB {
return when (error) {
ErrorA.Option1 -> Option1
ErrorA.Option2 -> Option2
}
}
fun from(error: ErrorB): ErrorAB {
return when (error) {
ErrorB.Option1 -> Option3
ErrorB.Option2 -> Option4
}
}
}
}
fun combineMethod() {
EitherT.singleFx<ErrorAB, String> {
val (something) = EitherT(UseCaseA().getSomething().k()).mapLeft { ErrorAB.from(it) }
val (converted) = EitherT(UseCaseB().convertSomething(something).k()).mapLeft { ErrorAB.from(it) }
converted
}
.subscribe(
object : SingleObserver<Either<ErrorAB, String>> {
override fun onSuccess(result: Either<ErrorAB, String>) {
when (result) {
is Either.Right -> System.out.println("Result is ${result.b}")
is Either.Left -> when (result.a) {
ErrorAB.Option1 -> System.out.println("Error is Option1")
ErrorAB.Option2 -> System.out.println("Error is Option2")
ErrorAB.Option3 -> System.out.println("Error is Option3")
ErrorAB.Option4 -> System.out.println("Error is Option4")
}.exhaustive
}
}
override fun onSubscribe(d: Disposable) {
// no-op
}
override fun onError(e: Throwable) {
System.err.println("onError($e)")
}
}
)
}
private val <T> T.exhaustive get() = run { }
private fun <E1, E2, T> EitherT<ForSingleK, E1, T>.mapLeft(mapper: (E1) -> E2): EitherT<ForSingleK, E2, T> {
return mapLeft(SingleK.functor(), mapper)
}
private fun <E, T> EitherTOf<ForSingleK, E, T>.backToSingle(): Single<Either<E, T>> = value().value()
private fun <E, R> EitherT.Companion.singleFx(
syntax: suspend MonadSyntax<EitherTPartialOf<ForSingleK, E>>.() -> R
): Single<Either<E, R>> {
return monad<ForSingleK, E>(SingleK.monad()).fx.monad(syntax).backToSingle()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.30")
implementation("io.arrow-kt:arrow-syntax:0.10.0")
implementation("io.arrow-kt:arrow-fx-rx2:0.10.0")
implementation("io.arrow-kt:arrow-mtl:0.10.0")
implementation("io.reactivex.rxjava2:rxjava:2.2.12")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment