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

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

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

Dd17014e380450cfed5d55ff20fa3dfd?s=128

Ryutaro Miyashita

June 12, 2017
Tweet

Transcript

  1. &JUIFSד
 䟝㹀ⰻךؒٓ٦ה
 䟝㹀㢩ךؒٓ٦׾
 ⴽ׮ךח׃׋ְ 3Y+B/JHIU7PM

  2. 㹧♴畆㣐龤 $IBU8PSL吳䒭⠓爡 ،فٔ؛٦ءّٝꟚ涪鿇ث٦ئ٦ت٦ !SZVHPP@

  3. ⹛堣  䟝㹀ⰻך㣟侁䟝㹀㢩ך㣟侁׾ⴓֽ׋ְ  䟝㹀ⰻ  8FC"1*ؙٔؒأزָة؎ي،ؐز׃׋  䟝㹀㢩 

    ءأذيך㉏겗זו
  4. 3Y+BWBךؒٓ٦عٝسؚٔٝ  0CTFSWBCMFPO&SSPS  'MPXBCMFPO&SSPS  4JOHMFPO&SSPS  $PNQMFUBCMFPO&SSPS 

    .BZCFPO&SSPS ؒٓ٦ך「ֽ《׶⯓כא
  5. ⢽ ؙٔحؙ̔ؿ؋؎ٕ《䖤̔،حفٗ٦س RxBinding.clicks(button) .map { /* Get file */ }

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

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

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

    /* Upload */ } ~~~~~ .subscribe({ /* Success */ }, { /* IOException or Request failure */ }) ؙٔحؙ؎كٝزכ׮ֲ굲׿דֿזְ ⢽ ؙٔحؙ̔ؿ؋؎ٕ《䖤̔،حفٗ٦س
  9.  ؒٓ٦عٝسؚٔٝؔلٖ٦ةכ葿ղ֮׷  PO&SSPS3FUVSO  PO&SSPS3FTVNF/FYU  SFUSZ  SFUSZ8IFO

     ˑؒٓ٦˒׏גז׿׌׏׋׏ֽ 3Y+BWBךؒٓ٦عٝسؚٔٝ
  10.  ؿ؋؎ָٕ鼅䫛ׁ׸גְזְךַ  ؿ؋؎ָٕ《䖤דֹזַ׏׋ךַ  ،حفٗ٦س㼎韋㢩ךؿ؋؎ٕ䕎䒭׌׏׋ךַ  8FC؟٦غ٦ָتؐٝ׃גְ׷ךַ  ؔؿٓ؎ٝזךַ

    ˑؒٓ٦˒ה♧〡ח鎉׏ג׮˘˘ ،فٔה׃גˑ姻׃ְ˒䮙⹛כؒٓ٦
  11. RxBinding.clicks(button) .map { /* Get file */ } .flatMap {

    /* Upload */ } ~~~~~ .subscribe({ if (it.isSuccessful) { /* Success */ } else { /* Request failure */ } }, { /* IOException */ }) PO/FYUח3FTVMU㘗׫׋ְז׮ך׾굲לׅ
  12. PO/FYUח &JUIFS׾굲לׅ

  13. 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
  14. 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
  15. public interface FoldJ<X, Y> { Y fold(X value); } 'PMEKBWB

  16. &JUIFS  אך㘗ךֲ׍ծְ׆׸ַ㘗ך⦼׾䭯א  ؟ـؙٓأה׃ג-FGU3JHIU㘗ָ֮׷  䧭⸆כ姻׃ְ SJHIU חַֽג3JHIUד鵤ׅ 

    㣟侁כ-FGUד鵤ׅ  3Y+BWBדכ-FGU׾5ISPXBCMFחׅ׷ה葺ׁ׉ֲ
  17. 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
  18. 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
  19. 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 ⡦㔐ד׮㣟侁׾鵤ֿׅהָדֹ׷
  20. 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 ׮׍׹׿䧭⸆׮⡦㔐ד׮鵤ֿׅהָדֹ׷
  21. ⢽ 0CTFSWBCMFDSFBUF a().subscribe({ either -> either.fold({ /* left, “it” is

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

    Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ })  4VCTDSJCFSPO/FYUך⚥ח׮ֲ媮「ֽ〡׾⡲׷  &JUIFS" #ד䭷㹀׃׋ˑ㘗˒ד穠卓׾「ֽ《׸׷
  23. ,PUMJOד׮׏הأو٦زחדֹזְַז

  24. sealed class Either<out A, out B> { abstract val isLeft:

    Boolean abstract val isRight: Boolean } &JUIFSLU
  25. &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 }
  26. &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) }
  27. &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) } ꟼ侧׾「ֽ《׏ג
  28. &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䒭ד㘗ח䘔ׄג㹋遤ׅ׷ꟼ侧׾ⴖ׶剏ִ
  29. 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
  30. 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 刿חأحؗٔ剅ֻֿהָדֹ׷
  31. ⢽ 0CTFSWBCMFDSFBUF b().subscribe({ either -> either.fold({ /* left, “it” is

    Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ }) +BWBד㹀纏׃׋הֹה「ֽ《׶倯כずׄ
  32. ׁ׵ח 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) }
  33. ׁ׵ח 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ד欽䠐
  34. ׁ׵ח 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׾欽䠐
  35. ׁ׵ח 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 */ })
  36. ׁ׵ח 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ָ֮׏ג׮
  37. ׁ׵ח 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ؔلٖ٦ةך״ֲח䮶׷莸ֲ
  38. ׁ׵ח 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זוד䕵甧א
  39. תה׭  䟝㹀ⰻך㣟侁䟝㹀㢩ך㣟侁׾ⴓֽ׋ְ  &JUIFS㘗׾⡲׏גⴓֽ׷ֿהָדֹ׷  ؔلٖ٦ة٦דכזֻ㘗דⴓֽ׷  ,PUMJO׾⢪ֲה刿חأو٦زח㹀纏דֹ׷ 

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