Elmで始めるFunctional Reactive Programming

11,618 views
11,498 views

Published on

ElmはHaskellと同じく純粋関数型言語のひとつで、ブラウザ上で動くアプリケーションの作成に特化しています。目に見えるものがすぐに作れるなど、関数型プログラミングやFRP(Functional Reactive Programming)の入門によい面がいくつかあります。JavaScriptなど型のない手続き型言語に慣れた人向けに関数型プログラミングのイメージを掴んでもらうことを目的にしています。

Published in: Technology

Elmで始めるFunctional Reactive Programming

  1. 1. フロントエンドに忍び寄る関数型の影 Elmで始める Functional Reactive Programming 前田康行 (@maeda_) 2013/2/23 大なごやjs
  2. 2. 自己紹介 !   前田康行 ( @maeda_ ) !   名古屋在住のフリーランス(http://www.illi-ichi.com) !   好きな言語 ! Scala !   Smalltalk ! DyNagoya (http://dynagoya.info/) = Dynamic language + Nagoya
  3. 3. この資料の目的 !   想定対象者 !   普段はJavascriptなど、型のない言語を使っている !   最近、関数型が流行っているらしいとは聞くが実態は 知らない !   または、関数型言語の勉強をしてみたが、実践的なア プリケーションの作り方は分からない !   そういった人たちに、関数型プログラミングの イメージを伝えることが目的です。 !   知らない用語が出てきても、スルーすれば大丈夫な はず。
  4. 4. Elmについて
  5. 5. Elm とは !   Elm (http://elm-lang.org) !   FRP(Functional Reactive Programming)をベースとした Webアプリケーションフレームワーク !   Elmのコード → Javascript + HTML + CSS を生成 !   HaskellをベースにWebアプリに適した文法を独自定義 !   Native Markdown support !   Extensible Records
  6. 6. 本家ページ(http://elm-lang.org) !   このページもElmで作られている
  7. 7. 本家ページ(http://elm-lang.org) !   サンプルが豊富 !   ブラウザ上でコードを試せる !   画面左のコードはサーバー側でコンパイルされて、 生成物が右側に表示される
  8. 8. Functional Reactive Programming
  9. 9. Reactive Programmingとは !   典型例:Excel !   A1やB1のセルの値を変えると、C1の値も勝手に変わる !   C1の中で、A1やB1はReactiveな値
  10. 10. もし、Javascriptで書いたら・・・ !   セルの状態を管理したり !   更新時のcallbackを設定したり const sum = function(outCell){ var x, y; function update(){ sheet(outCell).value(x + y); } return { updateX: function(cell) { x = cell.value(); update() }, updateY: function(cell) { y = cell.value(); update() } }; }("C1"); sheet("A1").on("update", sum.updateX); sheet("B1").on("update", sum.updateY); ※これは架空のコードです。
  11. 11. もし、Elmで書いたら・・・ !   このコードで、A1,B1の値が更新されたら、C1の 値が更新される main = lift (Excel.update "C1") $ (+) <〜 Excel.cell "A1" 〜 Excel.cell "B1" ※これは架空のコードです。
  12. 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本指で同時に描いた線 →
  13. 13. Callback地獄からの脱却 !   シングルスレッドなJSでは、コールバックが多用され る !   一般的に、Callbackはコードの流れを断絶し、可読性を 下げることが多い !   ElmならReactiveで、かつ、Functionalなコードが書ける
  14. 14. Functionalな プログラミング
  15. 15. Functionalなプログラミング とは 1.  (ただの)Functional Programming 関数を組み合わせてプログラムを構成 2.  Purely Functional Programming 純粋な関数(副作用がない関数)でプログラムを構成 (= 外界に影響を与えず、同じ引数には同じ戻り値を返す) !   副作用の例 !   マウスの位置やクリック状況を取得 !   画面に何かを描画する !   Ajax通信 !   時間を取得 !   変数の値(状態)を書き換える Elmは純粋な関数しか作れない!
  16. 16. 純粋な関数 副作用のないプログラミング 「外部から副作用をもらった時、どう副作用を与えるか」 を記述する。 Key Down Reactiveな値 (ライブラリとして提供) Timer 画面表示 実行時に変化があると、 値を純粋な関数に流し込む
  17. 17. 純粋な関数 副作用のないプログラミング 「外部から副作用をもらった時、どう副作用を与えるか」 を記述する。 Key Down Timer 画面表示 f1 f2 f3 f4 純粋な関数を合成して ひとつの関数を作る 外部の値をもらう時は 普通の適用とは異なる
  18. 18. 「意味イベント」を作る !   意味イベントという言葉はITプランニング小笠原さんが発案 http://www.itpl.co.jp/tech/func/event-driven.pdf !   生のイベントを変換/合成して、より意味のあるイベントに する 純粋な関数 Key Down Timer 画面表示 ダイアログ を閉じる ESCキーを 押下 Mouse Click ×ボタンを クリック 一定時間 経過
  19. 19. Elmで Programming
  20. 20. Elmは強い型付け言語 !   値には必ず型がつく。 ! Int, String, Float, ... !   [a](リスト), Set a(集合), Dict a(ハッシュテーブル) !   関数(A → B → C はA型とB型を受け取って、C型を返す関数) !   代数データ型、レコード !   関数に渡すときに、型が合わないとコンパイルエラー f1 :: Float →Int f2 :: Int→String 3.5 :: Float “□□□” :: String ※「a :: A」という表記はaがA型であることを  「A→B」という表記はA型からB型に変換する関数を示す 型チェック 型チェック
  21. 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. 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. 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
  24. 24. 最後に
  25. 25. 関数型言語の教材として Elmはよいのではないか? !   お手軽 !   ブラウザ上で、目に見える形で動作するアプリケーショ ンがすぐに試せる !   簡単 !   出来る事が限定されているのでHaskellよりも簡単 !   簡単側に倒れていることが多い !   IO Monadがない。Functorが分かれば大丈夫 !   ただしSignalのダイナミックな配線の変更はできない !   教育的 !   サンプルが豊富 !   サンプルのコメントにExerciseがあったり !   ピンポンゲームの作成チュートリアルもある !   標準ライブラリが弱いので、自分で定義しなくてはなら ない
  26. 26. 一方で、Elmの注意点 !   まだ発展途上。いろいろ厳しい !   コンパイルエラーが分かりにくい !   修行だと思ってください !   REPLがない !   型を調べたり、ちょっとした確認が面倒 !   ブラウザ上でHaskellを動かしたいわけではない。 !   Haskellをベースにブラウザ+FRPに適した構文を追求 !   Haskellは遅延評価だが、Elmは正格評価 遅延評価でFRPを実装するのは難しいらしい (メモリリークなどの観点で) !   where句は実装予定 !   特殊なifの構文
  27. 27. Elmを始めるには !   まずHaskellの勉強から !   「すごいHaskell楽しく学ぼう(通称:すごいH本)」 11章あたりまで読めれば十分。途中まででも多分大丈夫 !   Haskellの基本は分かったがアプリを作るイメージが 湧かない → そこでElmをやってみる !   サンプルを適当にいじってみたり !   ピンポンのチュートリアルやったり
  28. 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. 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/ を開く
  30. 30. 参考文献 !   Elm: Concurrent FRP for Functional GUIs http://www.testblogpleaseignore.com/wp-content/uploads/2012/04/thesis.pdf Elmの論文 !   イベントドリブンプログラミングの関数型的書き方 http://www.itpl.co.jp/tech/func/event-driven.pdf FRPという言葉のないFRPの説明(OCaml) ! maoeのブログ「FRPの話」 http://maoe.hatenadiary.jp/entry/2012/12/24/011414 包括的なFRPのまとめ(ほぼHaskell) ちなみにElmはArrowized FRP

×