- Elm Advent Calendar 2016 - Adventar 3日目
- Elmの勉強の記録
- 今回も読書ノート
読んだ章
- Richard Feldman, Elm in Action MEAP V03, pp.28-54
- the Elm Architectureに則ったサンプルアプリを作り上げる章
- 今回も再読
再読して今回学んだこと
Htmlモジュールの<タグ名> [...] [...]
はヘルパー関数
- 例によって分かりやすい図
- Htmlをレンダーするために使われるHtmlモジュール
-
node
関数がベースになる関数で、div ...
とかimg ...
という関数がヘルパー関数
node "img" [ src "logo.png" ] []
img [ src "logo.png" ] []
-
node
関数の使いどころ- 実はヘルパー関数は全てのhtmlタグについて用意されてない
- 非推奨タグ
<blink>
とかは用意されないない - ヘルパー関数がないときは、
node
関数を使う必要がある
- ヘルパー関数の引数は常に2つ
-
<img>
は子要素持たないので、img [src '1.png'] []
のように空ののリストを渡す - 属性も子要素もない
<br>
は、br [] []
になる
-
the Elm Architectureの説明のしかたについて
- アプリケーションの状態管理を行う、説明はシンプルで分かりやすかった
- elmランタイムもthe Elm Architectureに沿ったアプリ向けに最適化してる
- the Elm Architecture一択。ここがjsと違う
モジュールの関数の利用の仕方
- qualified style とunqualified styleという言い回しの意味を確認できた
- みかける表現だが把握してなかった
-
Html.div [...] [...]
というモジュール名を残した書き方が、qualified style - unqualified styleが、モジュール名を外した書き方
div [...] [...]
- qualifiedかどうかは、
... exposing...
されてるかどうか
import Html exposing (div, h1, img)
- これは、
div
,h1
,img
だけが、Html.
を外して書けるが、h2
やspan
はHtml.h2...
とかかないとダメ
import Html.Attributes exposing (..)
- これだと全てのヘルパー関数が
Html.
を外して書ける
基本的にqualified style(モジュール名.関数名
)式で書くべきとアドバイスしてる
-
filter
とか複数のモジュールで同じ名前の関数が普通に使われてるので、どちらを呼び出してるかが曖昧になるため
カンマが前にくるスタイル
view model =
div [ class "content" ]
[ h1 [] [ text "Photo Groove" ]
, div [ id "thumbnails" ]
[ img [ src "http://elm-in-action.com/1.jpeg" ] []
, img [ src "http://elm-in-action.com/2.jpeg" ] []
, img [ src "http://elm-in-action.com/3.jpeg" ] []
]
]
- elm-formatにかけてしまえば、このスタイルに統一されてしまうので慣れるしかない
- 利点としてリストのメンバー追加とか、修正箇所が最小になるとか、述べてる
- Evanはこのスタイルをチョイスした理由をforum(elm-discuss)で書いてたきがするがみつられず(見つけたら追記する)
elm makeのオプション
elm-make ./Main.elm --output elm.js
-
--output
オプションを使用してる -
html
側は、この生成されたelm.js
を読み込む
htmlページにビルドされたソースを使う
<div id="elm-area"></div>
<script src="elm.js"></script>
<script>
Elm.PhotoGroove.embed(document.getElementById("elm-area"));
</script>
- ビルドされたファイル(elmライタイムもバンドル)をロードすると、
Elm.PohotoGroove..
という形でElmオブジェクトにモジュールセットされる - Elmオブジェクトにセットされたモジュールに生えた
.embed()
に「elmアプリを展開させるdomノード」を渡すかたちで、初期化してる - Elmランタイムに出される指示
- PhotoGrooveモジュールを開く
- exposeされてるmainをエントリーポイントとして使う
- no module, no mainなら、エラー
the Elm ArchitectureのModel, ViewとElmランタイムの関係
elmランタイム
- eventリスナーの登録削除の
- スケジュール(http通信、dom更新)
- stateの保存と管理
このあたりは、Elmのコードはすべてdescriptionであり、実行はelmランタイムに委譲される、と言われたりするので、なるほどと納得した
elmではカリー化がデフォルトである
-
List.map
にModelと無名関数を渡す例で説明してる - the Elm ArchitectureにおけるModelはデータの定義
- カリー化をここでは、部分適用可能な関数、と説明されてる
- Elmはカリー化がデフォルト
- その比較で言えば、jsはタプル化がデフォルト
- 完全な引数のタプルがexpectされる
- 3つの引数を受ける関数に対して、2つだけ引数を渡した場合
- 引数を一つ受け取る関数が生成される
viewThumbnail selectedUrl thumbnail =
img
[ src (urlPrefix ++ thumbnail.url)
, classList [ ( "selected", selectedUrl == thumbnail.url ) ]
, onClick (SelectByUrl thumbnail.url)
]
[]
この引数2つ受け取って、<img>
(に相当するデータ)を返す関数 viewThumbnail
をリストmodel.photos
の目メンバーに順番に適用させるコードとして
List.map (\photo -> viewThumbnail model.selectedUrl photo) model.photos
が最初に紹介され、これをリファクタできるとして
List.map (viewThumbnail model.selectedUrl) model.photos
のように書き直しされる。(viewThumbnail model.selectedUrl)
部分が、部分適用の例
- elmの関数呼び出しは引数をスペースで区切って並べる
-
viewThumbnail model.selectedUrl
では、本来2つの引数を受け取る関数viewThumbnail
が引数1つしか受け取っていない- その結果、
(viewThumbnail model.selectedUrl)
は評価されると、引数1つを受け取る関数を得る
- その結果、
(\photo -> viewThumbnail model.selectedUrl photo)
が
(viewThumbnail model.selectedUrl)
と書き直すことができるのは、省略記法とかではなく、部分関数を部分適用してるだけ
- jsでカリー化しようとすると、関数を返す関数、を返す関数、・・・と実装を変形しないといけないところ
- elmだと全くそういう操作なく、関数の部分適用ができる。
- なので、「デフォルトでカリー化されてる」(curried by default)とか呼ばれたりする