Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Either で想定内のエラーと想定外のエラーを別ものにしたい!

Either で想定内のエラーと想定外のエラーを別ものにしたい!

Rx Ja Night Vol.2 (https://connpass.com/event/57150/)

Ryutaro Miyashita

June 12, 2017
Tweet

More Decks by Ryutaro Miyashita

Other Decks in Technology

Transcript

  1. ⢽ ؙٔحؙ̔ؿ؋؎ٕ《䖤̔،حفٗ٦س RxBinding.clicks(button) .map { /* Get file */ }

    .flatMap { /* Upload */ } ~~~~~ .subscribe({ /* Success */ }, { /* IOException or Request failure */ })
  2. RxBinding.clicks(button) .map { /* Get file */ } .flatMap {

    /* Upload */ } ~~~~~ .subscribe({ /* Success */ }, { /* IOException or Request failure */ }) ֿֿדPO&SSPSָ鸐濼ׁ׸׷ה ⢽ ؙٔحؙ̔ؿ؋؎ٕ《䖤̔،حفٗ٦س
  3. RxBinding.clicks(button) .map { /* Get file */ } .flatMap {

    /* Upload */ } ~~~~~ .subscribe({ /* Success */ }, { /* IOException or Request failure */ }) 4VCTDSJCFSPO&SSPSחⳢ椚ָ獳׶ ⢽ ؙٔحؙ̔ؿ؋؎ٕ《䖤̔،حفٗ٦س
  4. RxBinding.clicks(button) .map { /* Get file */ } .flatMap {

    /* Upload */ } ~~~~~ .subscribe({ /* Success */ }, { /* IOException or Request failure */ }) ؙٔحؙ؎كٝزכ׮ֲ굲׿דֿזְ ⢽ ؙٔحؙ̔ؿ؋؎ٕ《䖤̔،حفٗ٦س
  5. RxBinding.clicks(button) .map { /* Get file */ } .flatMap {

    /* Upload */ } ~~~~~ .subscribe({ if (it.isSuccessful) { /* Success */ } else { /* Request failure */ } }, { /* IOException */ }) PO/FYUח3FTVMU㘗׫׋ְז׮ך׾굲לׅ
  6. public abstract class Either<A, B> { public static <A, B>

    Either<A, B> left(A a) { new Left<>(a); } public static <A, B> Either<A, B> right(B b) { new Right<>(b); } public abstract boolean isLeft(); public abstract boolean isRight(); public abstract <X> X fold(Fold<A, X> l, Fold<B, X> r); } &JUIFSKBWB
  7. public class Left<A, B> extends Either<A, B> { private final

    A a; public Left(A a) { this.a = a; } @Override public boolean isLeft() { return true; } @Override public boolean isRight() { return false; } @Override public <X> X fold(Fold<A, X> l, Fold<B, X> r) { return l.fold(a); } } -FGUKBWB 3JHIUKBWB
  8. fun a(): Observable<Either<Throwable, String>> = Observable.create { it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException()))

    it.onNext(Either.right(“Hello”)) it.onNext(Either.right(“World”)) it.onNext(Either.right(“Foo Bar Buzz”)) } ⢽ 0CTFSWBCMFDSFBUF
  9. fun a(): Observable<Either<Throwable, String>> = Observable.create { it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException()))

    it.onNext(Either.right(“Hello”)) it.onNext(Either.right(“World”)) it.onNext(Either.right(“Foo Bar Buzz”)) } ⢽ 0CTFSWBCMFDSFBUF 䧭⸆儗כ4USJOH 㣟侁儗כ5ISPXBCMF׾䭯א&JUIFS
  10. fun a(): Observable<Either<Throwable, String>> = Observable.create { it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException()))

    it.onNext(Either.right(“Hello”)) it.onNext(Either.right(“World”)) it.onNext(Either.right(“Foo Bar Buzz”)) } ⢽ 0CTFSWBCMFDSFBUF ⡦㔐ד׮㣟侁׾鵤ֿׅהָדֹ׷
  11. fun a(): Observable<Either<Throwable, String>> = Observable.create { it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException())) it.onNext(Either.left(RuntimeException()))

    it.onNext(Either.right(“Hello”)) it.onNext(Either.right(“World”)) it.onNext(Either.right(“Foo Bar Buzz”)) } ⢽ 0CTFSWBCMFDSFBUF ׮׍׹׿䧭⸆׮⡦㔐ד׮鵤ֿׅהָדֹ׷
  12. ⢽ 0CTFSWBCMFDSFBUF a().subscribe({ either -> either.fold({ /* left, “it” is

    Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ })
  13. ⢽ 0CTFSWBCMFDSFBUF a().subscribe({ either -> either.fold({ /* left, “it” is

    Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ })  4VCTDSJCFSPO/FYUך⚥ח׮ֲ媮「ֽ〡׾⡲׷  &JUIFS" #ד䭷㹀׃׋ˑ㘗˒ד穠卓׾「ֽ《׸׷
  14. sealed class Either<out A, out B> { abstract val isLeft:

    Boolean abstract val isRight: Boolean } &JUIFSLU
  15. &JUIFSLU data class Left<out A, out B>(val value: A) :

    Either<A, B>() { override val isLeft: Boolean = true override val isRight: Boolean = false } data class Right<out A, out B>(val value: B) : Either<A, B>() { override val isLeft: Boolean = false override val isRight: Boolean = true }
  16. &JUIFSLU inline fun <A, B, X> Either<A, B>.fold( left: (A)

    -> X, right: (B) -> X ): X = when (this) { is Left -> left(value) is Right -> right(value) }
  17. &JUIFSLU inline fun <A, B, X> Either<A, B>.fold( left: (A)

    -> X, right: (B) -> X ): X = when (this) { is Left -> left(value) is Right -> right(value) } ꟼ侧׾「ֽ《׏ג
  18. &JUIFSLU inline fun <A, B, X> Either<A, B>.fold( left: (A)

    -> X, right: (B) -> X ): X = when (this) { is Left -> left(value) is Right -> right(value) } XIFO䒭ד㘗ח䘔ׄג㹋遤ׅ׷ꟼ侧׾ⴖ׶剏ִ
  19. fun b(): Observable<Either<Throwable, String>> = Observable.create { it.onNext(Left(RuntimeException())) it.onNext(Left(RuntimeException())) it.onNext(Left(RuntimeException()))

    it.onNext(Right(“Hello”)) it.onNext(Right(“World”)) it.onNext(Right(“Foo Bar Buzz”)) } ⢽ 0CTFSWBCMFDSFBUF
  20. fun b(): Observable<Either<Throwable, String>> = Observable.create { it.onNext(Left(RuntimeException())) it.onNext(Left(RuntimeException())) it.onNext(Left(RuntimeException()))

    it.onNext(Right(“Hello”)) it.onNext(Right(“World”)) it.onNext(Right(“Foo Bar Buzz”)) } ⢽ 0CTFSWBCMFDSFBUF 刿חأحؗٔ剅ֻֿהָדֹ׷
  21. ⢽ 0CTFSWBCMFDSFBUF b().subscribe({ either -> either.fold({ /* left, “it” is

    Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ }) +BWBד㹀纏׃׋הֹה「ֽ《׶倯כずׄ
  22. ׁ׵ח typealias RxEither<T> = Either<Throwable, T> typealias RxRight<T> = Right<Throwable,

    T> typealias RxLeft<T> = Left<Throwable, T> fun <T> Observable<T>.either(): Observable<RxEither<T>> = map { RxRight(it) as RxEither<T> } .onErrorReturn { RxLeft(it) }
  23. ׁ׵ח typealias RxEither<T> = Either<Throwable, T> typealias RxRight<T> = Right<Throwable,

    T> typealias RxLeft<T> = Left<Throwable, T> fun <T> Observable<T>.either(): Observable<RxEither<T>> = map { RxRight(it) as RxEither<T> } .onErrorReturn { RxLeft(it) } -FGU㘗ָ5ISPXBCMFך㘗׾UZQFBMJBTד欽䠐
  24. ׁ׵ח typealias RxEither<T> = Either<Throwable, T> typealias RxRight<T> = Right<Throwable,

    T> typealias RxLeft<T> = Left<Throwable, T> fun <T> Observable<T>.either(): Observable<RxEither<T>> = map { RxRight(it) as RxEither<T> } .onErrorReturn { RxLeft(it) } 䭁䓸ꟼ侧ד0CTFSWBCMFFJUIFS׾欽䠐
  25. ׁ׵ח fun c(): Observable<String> = Observable.create { it.onNext(“Hello, world”) it.onError(RuntimeException())

    } c().either().subscribe({ either -> either.fold({ /* left, “it” is Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ })
  26. ׁ׵ח fun c(): Observable<String> = Observable.create { it.onNext(“Hello, world”) it.onError(RuntimeException())

    } c().either().subscribe({ either -> either.fold({ /* left, “it” is Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ }) 兛鸐ך0CTFSWBCMFָ֮׏ג׮
  27. ׁ׵ח fun c(): Observable<String> = Observable.create { it.onNext(“Hello, world”) it.onError(RuntimeException())

    } c().either().subscribe({ either -> either.fold({ /* left, “it” is Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ }) 䭁䓸ꟼ侧דFJUIFSؔلٖ٦ةך״ֲח䮶׷莸ֲ
  28. ׁ׵ח fun c(): Observable<String> = Observable.create { it.onNext(“Hello, world”) it.onError(RuntimeException())

    } c().either().subscribe({ either -> either.fold({ /* left, “it” is Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ }) 0CTFSWBCMFNFSHFזוד䕵甧א
  29. תה׭  䟝㹀ⰻך㣟侁䟝㹀㢩ך㣟侁׾ⴓֽ׋ְ  &JUIFS㘗׾⡲׏גⴓֽ׷ֿהָדֹ׷  ؔلٖ٦ة٦דכזֻ㘗דⴓֽ׷  ,PUMJO׾⢪ֲה刿חأو٦زח㹀纏דֹ׷ 

    䭁䓸ꟼ侧׾⢪׏ג傀㶷ך0CTFSWBCMF׮
 &JUIFS5ISPXBCMF 5ח㢌䳔〳腉  &JUIFS荈⡤כ4DBMBח׮׏הؼٝزָ֮׷  -FGU 3JHIUךNBQװTXBQזוזו