27
FRP Functional Reactive Programming 2014/08/01 Ryo Kamimura

FRP - Functional Reactive Programming

Embed Size (px)

DESCRIPTION

関数リアクティブプログラミングをAndroidやiOSで使ってみた話

Citation preview

FRPFunctional Reactive Programming

2014/08/01

Ryo Kamimura

いいか、みんな

         (゚д゚ )         (| y |)

  関数型プログラミングの要素をリアクティブプログラミングに合わせると

    関数型 (゚д゚) リアクティブ      \/| y |\/

      FRPになるのだ

         ( ゚ д゚) FRP         (\/\/

(reactive)

( )

( ) (behavior)

(stateless)

(immutable)

(map, filter, fold)

Java Objective-C

FRP

RxJava

compile 'com.netflix.rxjava:rxjava-core:+'

ReactiveCocoa

pod 'ReactiveCocoa'

Push PullPush

Pull

( )

Pull

java.lang.Iterable, RACSequence(ReactiveCocoa)

Push

rx.Observable(RxJava), RACSignal(ReactiveCocoa)

Push

PushUI

3

next

completed

error

(Java)

ViewObservable.input(mEditText, false)

.subscribe(new Action1<String>() {

@Override

public void call(String s) {

Log.d("LOG", "New value: " + s);

}

}, new Action1<Throwable>() {

@Override

public void call(Throwable t) {

Log.d("LOG", "Error: " + t.getMessage());

}

}, new Action0() {

Override

public void call() {

Log.d("LOG", "Completed.");

}

});

(Objective-C)

[self.textField.rac_textSignal subscribeNext:^(id x){ NSLog(@"New value: %@", x);} error:^(NSError *error){ NSLog(@"Error: %@", error);} completed:^{ NSLog(@"Completed.");}];

FRPKVO

UI

Transformation

Filtering

Combining

Injection

Transformationmap() / map:

flatMap() / flattenMap:

Filteringfilter() / filter:

skip() / skip:

throttleWithTimeout() / throttle:

Combiningmerge() / merge:

zip() / zip:reduce:

InjectiondoOnEach() / doNext:

doOnCompleted() / doCompleted:

doOnError() / doError:

FRP1.

2.

3. 500

4.

5.

Java 8ViewObservable.input(mEditText, false)

.filter(text -> {

// 入力値をチェックして

return isValidText(text);

})

.throttleWithTimeout(500, TimeUnit.MILLISECONDS) // 500ミリ秒以内

.flatMap(text -> {

// 入力値をサーバーに送信

return sendTextObservable(text);

})

.flatMap(jsonResponse -> {

// レスポンスの値を使って再度サーバーからデータ取得

return resultObservable(jsonResponse.get("result"));

})

.observeOn(AndroidSchedulers.mainThread()) // UIスレッドで

.subscribe(jsonResponse -> {

// UIを更新

}, throwable -> {

Log.d("LOG", "An error occurred: " + throwable.getMessage());

});

Objective-C

[[[[[[[self.textField rac_textSignal]

filter:^BOOL(NSString *text) {

// 入力値をチェックして

@strongify(self)

return [self isValidText:text];

}]

throttle:0.5] // 500ミリ秒以内

flattenMap:^RACStream *(NSString *text) {

// 入力値をサーバーに送信

@strongify(self)

return [self signalForSendText:text];

}]

flattenMap:^RACStream *(NSDictionary *jsonResponse) {

// レスポンスの値を使って再度サーバーからデータ取得

@strongify(self)

return [self signalForResult:jsonResponse[@"result"]]

}]

deliverOn:[RACScheduler mainThreadScheduler]] // UIスレッドで

subscribeNext:^(NSDictionary *jsonRespoonse) {

// UIを更新

} error:^(NSError *error) {

NSLog(@"An error occurred: %@", error);

}];

FRPGUI

UI

Push

GUION/OFF

(Spinner/UIPickerView)

Non-FRPUI

FRP

iOS Android

Java Java8 (+ Retrolambda)

Objective-C

Groovy Swift

THE END