Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

⹛堣  䟝㹀ⰻך㣟侁䟝㹀㢩ך㣟侁׾ⴓֽ׋ְ  䟝㹀ⰻ  8FC"1*ؙٔؒأزָة؎ي،ؐز׃׋  䟝㹀㢩  ءأذيך㉏겗זו

Slide 4

Slide 4 text

3Y+BWBךؒٓ٦عٝسؚٔٝ  0CTFSWBCMFPO&SSPS  'MPXBCMFPO&SSPS  4JOHMFPO&SSPS  $PNQMFUBCMFPO&SSPS  .BZCFPO&SSPS ؒٓ٦ך「ֽ《׶⯓כא

Slide 5

Slide 5 text

⢽ ؙٔحؙ̔ؿ؋؎ٕ《䖤̔،حفٗ٦س RxBinding.clicks(button) .map { /* Get file */ } .flatMap { /* Upload */ } ~~~~~ .subscribe({ /* Success */ }, { /* IOException or Request failure */ })

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

 ؒٓ٦عٝسؚٔٝؔلٖ٦ةכ葿ղ֮׷  PO&SSPS3FUVSO  PO&SSPS3FTVNF/FYU  SFUSZ  SFUSZ8IFO  ˑؒٓ٦˒׏גז׿׌׏׋׏ֽ 3Y+BWBךؒٓ٦عٝسؚٔٝ

Slide 10

Slide 10 text

 ؿ؋؎ָٕ鼅䫛ׁ׸גְזְךַ  ؿ؋؎ָٕ《䖤דֹזַ׏׋ךַ  ،حفٗ٦س㼎韋㢩ךؿ؋؎ٕ䕎䒭׌׏׋ךַ  8FC؟٦غ٦ָتؐٝ׃גְ׷ךַ  ؔؿٓ؎ٝזךַ ˑؒٓ٦˒ה♧〡ח鎉׏ג׮˘˘ ،فٔה׃גˑ姻׃ְ˒䮙⹛כؒٓ٦

Slide 11

Slide 11 text

RxBinding.clicks(button) .map { /* Get file */ } .flatMap { /* Upload */ } ~~~~~ .subscribe({ if (it.isSuccessful) { /* Success */ } else { /* Request failure */ } }, { /* IOException */ }) PO/FYUח3FTVMU㘗׫׋ְז׮ך׾굲לׅ

Slide 12

Slide 12 text

PO/FYUח &JUIFS׾굲לׅ

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

public class Left extends Either { 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 fold(Fold l, Fold r) { return l.fold(a); } } -FGUKBWB 3JHIUKBWB

Slide 15

Slide 15 text

public interface FoldJ { Y fold(X value); } 'PMEKBWB

Slide 16

Slide 16 text

&JUIFS  אך㘗ךֲ׍ծְ׆׸ַ㘗ך⦼׾䭯א  ؟ـؙٓأה׃ג-FGU3JHIU㘗ָ֮׷  䧭⸆כ姻׃ְ SJHIU חַֽג3JHIUד鵤ׅ  㣟侁כ-FGUד鵤ׅ  3Y+BWBדכ-FGU׾5ISPXBCMFחׅ׷ה葺ׁ׉ֲ

Slide 17

Slide 17 text

fun a(): Observable> = 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

Slide 18

Slide 18 text

fun a(): Observable> = 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

Slide 19

Slide 19 text

fun a(): Observable> = 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 ⡦㔐ד׮㣟侁׾鵤ֿׅהָדֹ׷

Slide 20

Slide 20 text

fun a(): Observable> = 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 ׮׍׹׿䧭⸆׮⡦㔐ד׮鵤ֿׅהָדֹ׷

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

⢽ 0CTFSWBCMFDSFBUF a().subscribe({ either -> either.fold({ /* left, “it” is Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ })  4VCTDSJCFSPO/FYUך⚥ח׮ֲ媮「ֽ〡׾⡲׷  &JUIFS" #ד䭷㹀׃׋ˑ㘗˒ד穠卓׾「ֽ《׸׷

Slide 23

Slide 23 text

,PUMJOד׮׏הأو٦زחדֹזְַז

Slide 24

Slide 24 text

sealed class Either { abstract val isLeft: Boolean abstract val isRight: Boolean } &JUIFSLU

Slide 25

Slide 25 text

&JUIFSLU data class Left(val value: A) : Either() { override val isLeft: Boolean = true override val isRight: Boolean = false } data class Right(val value: B) : Either() { override val isLeft: Boolean = false override val isRight: Boolean = true }

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

&JUIFSLU inline fun Either.fold( left: (A) -> X, right: (B) -> X ): X = when (this) { is Left -> left(value) is Right -> right(value) } XIFO䒭ד㘗ח䘔ׄג㹋遤ׅ׷ꟼ侧׾ⴖ׶剏ִ

Slide 29

Slide 29 text

fun b(): Observable> = 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

Slide 30

Slide 30 text

fun b(): Observable> = 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 刿חأحؗٔ剅ֻֿהָדֹ׷

Slide 31

Slide 31 text

⢽ 0CTFSWBCMFDSFBUF b().subscribe({ either -> either.fold({ /* left, “it” is Throwable */ }, { /* right, “it” is String */ }) }, { /* Error */ }) +BWBד㹀纏׃׋הֹה「ֽ《׶倯כずׄ

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

ׁ׵ח typealias RxEither = Either typealias RxRight = Right typealias RxLeft = Left fun Observable.either(): Observable> = map { RxRight(it) as RxEither } .onErrorReturn { RxLeft(it) } 䭁䓸ꟼ侧ד0CTFSWBCMFFJUIFS׾欽䠐

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

ׁ׵ח fun c(): Observable = 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ָ֮׏ג׮

Slide 37

Slide 37 text

ׁ׵ח fun c(): Observable = 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ؔلٖ٦ةך״ֲח䮶׷莸ֲ

Slide 38

Slide 38 text

ׁ׵ח fun c(): Observable = 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זוד䕵甧א

Slide 39

Slide 39 text

תה׭  䟝㹀ⰻך㣟侁䟝㹀㢩ך㣟侁׾ⴓֽ׋ְ  &JUIFS㘗׾⡲׏גⴓֽ׷ֿהָדֹ׷  ؔلٖ٦ة٦דכזֻ㘗דⴓֽ׷  ,PUMJO׾⢪ֲה刿חأو٦زח㹀纏דֹ׷  䭁䓸ꟼ侧׾⢪׏ג傀㶷ך0CTFSWBCMF׮
 &JUIFS5ISPXBCMF 5ח㢌䳔〳腉  &JUIFS荈⡤כ4DBMBח׮׏הؼٝزָ֮׷  -FGU 3JHIUךNBQװTXBQזוזו

Slide 40

Slide 40 text

ֶ׃תְ IUUQTHJUIVCDPNSZVHPP&JUIFS4BNQMF