12. ブラウザ上でもReactiveがいい
! マルチタッチ対応のお絵描きアプリも5行で
(本家ページのBasic – Touch – Drawのサンプル)
add
t
d
=
let
vs
=
Dict.findWithDefault
[]
t.id
d
in
Dict.insert
t.id
((t.x,t.y):vs)
d
scene
(w,h)
=
collage
w
h
.
map
(solid
red
.
line)
main
=
let
ts
=
foldp
(
ts
d
->
foldl
add
d
ts)
Dict.empty
Touch.touches
in
lift2
scene
Window.dimensions
(lift
Dict.values
ts)
※これは架空のコードではありません。
3本指で同時に描いた線 →
21. Reactiveな世界
純粋な世界
Signal a型
(aは何かの型)
! 純粋な値と外部からやってくる値を型で区別
! 外からやってくるReactiveな値は「Signal a型」となる
(aには純粋な世界の型が入る)
! 「Signal Int型」は何らかの数値(Int)の値となるReactiveな値を表す
Int
String
Element
Time
Signal Int
Signal String
Signal Element
Signal Time
22. Reactiveな値を変換する
! Reactiveな値を変換する場合、関数をReactiveな世
界に持ち上げて(liftして)、適用する
Reactiveな世界
純粋な世界
format :: Int → String
Mouse.x :: Signal Int
30 :: Int
"X座標は30です" :: String
"X座標は□です" :: Signal String
lift format
:: Signal Int → Signal String
23. Signal Element型に持っていく
! 画面に表示されるものはElement型で表される
! Signal a型の値を変換して、
最終的にSignal Element型を作るようなmain関数を作る
--
マウスカーソルに合わせて画像をリサイズする
drawImage
(w,
h)
=
image
w
h
"/images/hoge.jpg"
main
=
lift
drawImage
Mouse.position
drawImage :: (Int, Int) → Element
lift drawImage :: Signal (Int, Int) → Signal Element
Mouse.position :: Signal (Int, Int)
main :: Signal Element
28. (おまけ)
説明しきれなかったこと
! 状態を扱いたい → foldpを使う
foldp :: (a → b → b) → b → Signal a → Signal b
! Javascriptとの連携(FFI)
! JS側で登録したイベントをSignal aとしてElmで扱う
! ElmのSignal aをイベントとしてJS側に渡す
! Applicativeスタイルでの記述
(<〜) :: (a → b) → Signal a → Signal b
(〜) :: Signal (a → b) → Signal a → Signal b
29. (おまけ)
elm-serverをローカルで立てる
! Mac OS X で home brew を使用した場合
>
brew
install
ghc
>
brew
install
cabal-install
>
cd
(git
repos)
>
git
clone
https://github.com/evancz/Elm.git
>
cd
Elm/elm
>
cabal
install
Elm.cabal
>
cd
(git
repos)
>
git
clone
https://github.com/evancz/elm-lang.org.git
>
cd
elm-lang.org/
>
./compile.sh
>
./server/Server
ブラウザでhttp://localhost:8000/ を開く