平日ワイ
ワイ「優秀な若者たちが高速で仕事を終わらせてもうたから、ワイのやる事なくなってもうたで」
ワイ「弊社の10%ルール1を使って新しい言語のお勉強でもしてみよか」
ワイ「こないだ何かのランキングでナンバーワンやったあの言語、なんやったっけな」
ワイ「・・・せや、Elmや」
ワイ「純粋関数型言語いうやつやな」
ワイ「ちょっとそのElmちゃんでも勉強してみよか」
とりあえずググる
ワイ「Elm、日本語・・・検索っと」
ワイ「おお、なんか**とっても親切そうなサイトが見つかったで」
ワイ「・・・なるほどな〜」
ワイ「ElmいうんはJavaScriptにコンパイルできる言語なんやな」
ワイ「フロントエンドなワイにピッタリやないか」
ワイ「しかも、環境構築とかせんでも」
ワイ「Ellie**いうサイト上で動かしてみることも出来るみたいや」
とりあえずHello World
ワイ「まずElmではどうやって文字とかタグを表示させんねやろ」
ワイ「ふむふむ」
ワイ「こうか?」
view model =
div [ class "container" ] [ text "Hello World" ]
ワイ「おお、Hello Worldが表示されたで」
ワイ「しかし文法がよう分からへんで」
どういう文法
ワイ「view modelいうのは何や?」
ワイ「なになに、ええと」
ワイ「どうやらこれはviewという名前の関数を定義してるみたいや」
ワイ「ほんでmodelいうのが引数やな」
ワイ「このviewいう関数にはmodelいう引数が渡ってくる想定ですよ〜、っていう」
ワイ「仮引数ってやつや」
ワイ「ほなその下の」
div [ class "container" ] [ text "Hello World" ]
ワイ「↑これは何してんねん」
ワイ「ええと、なんや、このdivいうのも関数なんか」
ワイ「divという関数を使うと**divタグが生成される**、いうイメージやな」
ワイ「ほえ〜」
ワイ「divいう関数に[ class "container" ]と[ text "Hello World" ]という」
ワイ「2つの引数を渡して実行してやる。すると・・・」
ワイ「第一引数の[ class "container" ]が、divタグの属性値、つまりクラスとかに変わって」
ワイ「第二引数の[ text "Hello World" ]が、divタグの中身になるんやな」
ワイ「pとかspan、ul、liとかも関数として用意されとるみたいや」
ワイ「そういえば、戻り値を返すのにreturnとかは書かんくてもええんやな」
ワイ「今回でいうとdiv関数の結果が、自動的にview関数の戻り値になるみたいや」
ワイ「その関数の中で最後に評価した値が、自動的に戻り値になるいうことやな」
関数がコンポーネントみたいに使える
ワイ「タグの中に更にタグを書きたい場合は」
div [ class "container" ]
[ p [] [ text "Hello" ]
, p [] [ text "World" ]
]
ワイ「↑こう書けば」
<div class="container">
<p>Hello</p>
<p>World</p>
</div>
ワイ「↑こういうhtml要素たちを生成してくれるんやな」
ワイ「ビューを全部関数で書くなんてオモロイなあ」
ワイ「これを変数にでも入れておけば、それだけでコンポーネントとして使いまわせるやん」
ワイ「しかもただの変数や関数やから、プログラムの中に自然と溶け込ませることが出来るな」
ワイ「配列の分だけ回してコンポーネントを表示、とか」
ワイ「そんな時に便利そうや」
双方向バインディングでもしてみる
ワイ「ほな次はElmを使って、よくある双方向バインディングでもしてみよか」
ワイ「双方向バインディングいうんは」
ワイ「inputタグにテキストを入力すると、その値が即座にJS側に渡されて」
ワイ「ページの他の部分のDOMにもその値が反映される、みたいなやつや」
ワイ「Vue.jsとかでようやるやつやな」
ワイ「じゃあ今回は」
ユーザーが
inputタグに数値を入力したら、
その数値が他のDOMにも表示される
ワイ「↑これを作ってみよか」
どんな情報を管理していくかをModelとして定義
ワイ「まずModelいう、状態を表す型を定義するんや」
ワイ「Elmは静的型付言語やからな」
ワイ「ほな、ユーザーが入力した数値はuserInputNumberいう名前で管理していこか」
type alias Model =
{ userInputNumber : Int
}
ワイ「userInputNumber という整数の状態を管理していきますよ、と」
ワイ「ユーザーの入力によって、整数の値が変わったら」
ワイ「それを表示内容に反映させてやるためやな」
ワイ「ほんで、次はそのModelの初期状態をinitいう名前で定義するんや」
init : Model
init =
{ userinputnumber = 0
}
ワイ「init : Modelいうのは」
ワイ「initという値はModel型の値ですよ、いう意味や」
ワイ「型注釈いうやつやな」
ワイ「あれ、エラーが出てもうた」
型の不一致
ヒント:レコードフィールドの間違いのようです。
たぶんuserinputnumberはuserInputNumberであるべきでは?
ワイ「おお、userInputNumberはキャメルケースのはずやのに」
ワイ「initの中では全部小文字で書いてたわ」
ワイ「ていうか、コンパイラがタイポを指摘してくれたで」
ワイ「なんちゅう優しさや」
ワイ「さっき定義したModelと、今書いたinitの中身が違ってると」
ワイ「ちゃんと怒ってくれるわけやな」
ワイ「そのためにはinitを定義するときにちゃんと型注釈を書いて」
ワイ「initという値は、Model型の値ですよ」
ワイ「って表明しとかなアカンけどな」
ワイ「型注釈をきちんと書いておくと、コードを読む人間にとっても」
ワイ「initという値はModel型の値なんやな!」
ワイ「ほなuserInputNumberいう値が中にあるはずやな!」
ワイ「とかって分かるし」
ワイ「もし間違った値を入れようとしたら」
Model型や言うてたのに、違う値を入れようとしてまっせ!
ワイ「ってコンパイラが怒ってくれんねん」
ワイ「型注釈を書くことで、コンパイラにもコードを読む人間にも注意を促せるわけやな」
ワイ「型注釈は」
ワイ「人間もコンパイラも読めるドキュメント」
ワイ「って、ぴくすふぁんくさん(@pxfnc)も言うてたな」
ワイ「ほな、次はinputタグに入力した文字列をElm側で受け取る部分を書いていこか・・・」
〜続く〜
続編書いたで!
今回のコード
**Ellie**で見れるから好きにいじってみてや。
-
業務時間の10%(週4時間)を好きな研究・勉強に使っていいという制度 ↩