狠狠撸

狠狠撸Share a Scribd company logo
Re?exの紹介
@nakau
自己紹介
? Nakau Rie
? 職業:プログラマー
? twitter: @nakau
? ソシャゲ: おつかれ山
コンテンツ
? Functional Reactive Programming
? Re?ex
Functional Reactive
Programming
FRP
? インタラクティブなソフトウェアを
? pure 蹿耻苍肠迟颈辞苍で実现するためのパラダイム
Interactive software
https://?ic.kr/p/3Jaze
https://www.google.com/maps
Interactive software
? on Programming
? INPUTの受け入れ
? イベント&イベントハンドラ
? ステート管理
? UIレンダリング etc.
pure function
? 副作用がない
? 関数の外部にある変数やデータを変更しない
? 一貫性がある
? 同じ入力データを与えられると常に同じ値を返す
FRP
? 入力やイベントを定義された型に当てはめる
? 定義された型に当てはめるの変換をモジュール化
? → 副作用のある関数を少なく
var v = "";
function a(){
v += "a";
}
function b(){
v += "b";
}
a(); // v = "a"
a(); // v = "aa"
b(); // v = "aab"
b(); // v = "aabb"
var v = "";
function a(v){
return v += "a";
}
function b(v){
return v += "b";
}
v = a(v); // v = "a"
v = a(v); // v = "aa"
v = b(v); // v = "aab"
v = b(v); // v = "aabb"
function join(line,n){ return line + n; }
timeline = [""];
timeline.reduce(join);// ""
timeline = ["","a"];
timeline.reduce(join); // "a"
timeline = ["","a","a"];
timeline.reduce(join); // "aa"
timeline = ["","a","a","b"];
timeline.reduce(join); // "aab"
timeline = ["","a","a","b","b"];
timeline.reduce(join); // "aabb"
Behavior
? 時間とともに動的に変化する1つ1つの値
? Behaviorの時間は連続的
? Behaviorを順番通りに処理して動的な値を表す
? B=[V1,V2,V3,V4,…]
? B[T1]→V1
Event
? データの流れを時間と値のペアで表す
? Eventの時間は離散的
? E=[(T1,V1),(T2,V2),…]
? Tは時間を表し、Eventの識別子になる
文字入力???時間の流れ(連続的)
B=[""];
B=["","メ"];
B=["","メ","メロ"];
B=["","メ","メロ","メロン"];
マウスクリック???時間の流れ(ばらばら)
E=[(0, (0,0))]
E=[(0, (0,0)), (25, (300,200))]
E=[(0, (0,0)), (25, (300,200)), (30, (310,250))]
FRP Library
? Haskell
? Reactive
? Yampa
? reactive-banana
? Javascript
? RxJS
? Bacon.js
Re?ex
Re?ex is a high-performance, deterministic, higher-order
Functional Reactive Programming system
Re?ex
? FRPシステム
? pull / push 式
? WEBアプリケーション
? コンパイラ … GHC
Re?ex.DOM
? HTML DOM操作をRe?exシステム上で行う
? DOM要素でおこるイベントをFRPで処理
? GHCJS.DOMがベース
install
? cabal-install
? try-re?ex
? https://github.com/ryantrinkle/try-re?ex
cabal install re?ex-dom
./try-re?ex
To create a simple web GUI:
$ cat >hello.hs <<EOF
import Re?ex.Dom
main = mainWidget $ text "Hello, world!"
EOF
$ ghcjs hello.hs
Then navigate your browser to
?le:///path/to/try-re?ex/hello.jsexe/index.html
/hello.jsexe
- all.js
- index.html
- lib.js
- manifest.webapp
- out.js
- out.stats
- rts.js
- runmain.js
搁别蹿濒别虫の绍介
Hello World
import Reflex.Dom
main = mainWidget $ text "Hello, world!"
<html>
<head>…</head>
<body>Hello, world!</body>
</html>
hello.hs
Widget
? Re?exシステムにおけるDOM
? アプリケーションはmainWidgetから始まる
? IOアクションを返す
? text , el , textInputもWidget
mainWidget :: Widget Spider (Gui Spider (WithWebView
SpiderHost) (HostFrame Spider)) () -> IO ()
text
? DOMのテキストノードを表すWidget
? arg1 …テキストノードとなる文字列
? return … テキストノードWidget
text :: MonadWidget t m => String -> m ()
el
? HTML Elementを表すWidget
? arg1 …タグとなる文字列
? arg2 …タグの子要素になるWidget
? return … Widget
el :: MonadWidget t m => String -> m a -> m a
DOMの構築1
import Reflex.Dom
main = mainWidget $ el “div" $ text
"Hello, world!"
<html>
<head>
…
</head>
<body>
<div>Hello, world!</div>
</body>
</html>
DOMの構築2
import Reflex.Dom
main = mainWidget $ el "div" $ do
el "h1" $ text "タイトル"
el "p" $ text "文章"
<html>
<head>…</head>
<body>
<div>
<h1>タイトル</h1>
<p>文章</p>
</div>
</body>
</html>
text
text :: MonadWidget t m => String -> m ()
el
el :: MonadWidget t m => String -> m a -> m a
Re?ex.Dynamic
? Re?exの動的に変化する値
? Behavior , Event → Dynamic
? Re?ex.DOM
? 要素が持つ値の変化やイベントを表現
data Dynamic t a
= Dynamic (Behavior t a) (Event t a)
Re?ex.Event
? Event発生の流れを表す
? 1つの発生につき、1つのデータを持つ
? occurrence type
? never … 発生しないイベントを作る関数
動的な値
1. import Reflex.Dom
2.
3. main = mainWidget $ el "div" $ do
4. tx <- textInput
5. dynText $ _textInput_value tx
dynText
dynText :: MonadWidget t m => Dynamic t
String -> m ()
? text関数のDynamic Stringを受け取る版
? 引数 … Dynamic t String
? return … textノードWidget
textInput
dynText :: MonadWidget t m
=> Dynamic t String -> m ()
? テキスト入力フィールドWidgetを返す関数
? 引数 … なし
? return … テキスト入力Widget
? input
? 初期値や属性を指定できる
textInputの機能
data TextInput t
= TextInput {
_textInput_value :: Dynamic t String
, _textInput_keypress :: Event t Int
, _textInput_keydown :: Event t Int
, _textInput_keyup :: Event t Int
, _textInput_hasFocus :: Dynamic t Bool
, _textInput_element :: HTMLInputElement
}
Dynamicの変換
1.import Reflex
2.import Reflex.Dom
3.import Safe (readMay)
5.main = mainWidget $ do
6. result <- numberInput
7. resultString <- mapDyn show result
8. dynText resultString
9.
10.numberInput :: MonadWidget t m => m
(Dynamic t (Maybe Double))
11.numberInput = do
12. n <- textInput
13. mapDyn readMay $ _textInput_value n
elの機能
data El t
= El { _el_element :: HTMLElement
, _el_clicked :: Event t ()
, _el_keypress :: Event t Int
, _el_scrolled :: Event t Int
}
でも
搁别?别虫を试してみて
よいところ
? try-re?exが簡単
? Re?ex.DOM, GHCJS
? ポータブル
? GHC言語拡張に親しむ
? RecursiveDo, TemplateHaskell, QuasiQuotes
? Re?ex単体でも使える
注意する点
? Re?ex.DOM, GHCJS
? 実行するブラウザはChromeがよさそう
? javascriptで動く
? メモリリーク
資料
hackage : Re?ex
https://hackage.haskell.org/package/re?ex
try-refrex README
https://github.com/ryantrinkle/try-re?ex/blob/master/README.md
Reddit :
http://www.reddit.com/r/haskell/comments/31rat9/
re?ex_practical_functional_reactive_programming/
YouTube : Re?ex: Practical Functional Reactive Programming
https://www.youtube.com/watch?v=dOy7zIk3IUI
</script>

More Related Content

搁别蹿濒别虫の绍介