わざわざ学ばなくてもいい言語ランキング1位の「Elm」をわざわざ学んでみる

## 平日ワイ
ワイ「優秀な若者たちが高速で仕事を終わらせてもうたから、ワイのやる事なくなってもうたで」
ワイ「弊社の**10%ルール[^1]**を使って新しい言語のお勉強でもしてみよか」
ワイ「こないだ**[何かのランキング](https://qiita.com/rana_kualu/items/5be7a827ed370c3cc67f)**で**ナンバーワン**やったあの言語、なんやったっけな」
ワイ「・・・せや、**Elm**や」
ワイ「**純粋関数型言語**いうやつやな」
ワイ「ちょっとその**Elm**ちゃんでも勉強してみよか」

## とりあえずググる
ワイ「Elm、日本語・・・検索っと」
ワイ「おお、なんか**[とっても親切そうなサイト](https://guide.elm-lang.jp/)**が見つかったで」
ワイ「・・・なるほどな〜」
ワイ「Elmいうんは**JavaScriptにコンパイルできる言語**なんやな」
ワイ「フロントエンドなワイにピッタリやないか」
ワイ「しかも、環境構築とかせんでも」
ワイ「**[Ellie](https://ellie-app.com/)**いうサイト上で動かしてみることも出来るみたいや」

## とりあえず`Hello World`
ワイ「まずElmではどうやって**文字**とか**タグ**を表示させんねやろ」
ワイ「ふむふむ」
ワイ「こうか？」


```elm
view model =
    div [ class "container" ] [ text "Hello World" ]
```

ワイ「おお、`Hello World`が表示されたで」
ワイ「しかし文法がよう分からへんで」

## どういう文法
ワイ「`view model`いうのは何や？」
ワイ「なになに、ええと」
ワイ「どうやらこれは`view`という名前の**関数**を定義してるみたいや」
ワイ「ほんで`model`いうのが**引数**やな」
ワイ「この`view`いう関数には`model`いう引数が渡ってくる想定ですよ〜、っていう」
ワイ「**仮引数**ってやつや」

ワイ「ほなその下の」

```elm
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`関数の戻り値になるみたいや」
ワイ「その関数の中で最後に評価した値が、自動的に戻り値になるいうことやな」

## 関数がコンポーネントみたいに使える
ワイ「タグの中に更にタグを書きたい場合は」

```elm
div [ class "container" ]
    [ p [] [ text "Hello" ]
    , p [] [ text "World" ]
    ]
```

ワイ「↑こう書けば」

```html
<div class="container">
    <p>Hello</p>
    <p>World</p>
</div>
```

ワイ「↑こういうhtml要素たちを生成してくれるんやな」

ワイ「ビューを全部関数で書くなんてオモロイなあ」
ワイ「これを変数にでも入れておけば、それだけで**コンポーネントとして使いまわせる**やん」
ワイ「しかもただの変数や関数やから、プログラムの中に自然と溶け込ませることが出来るな」
ワイ「配列の分だけ回してコンポーネントを表示、とか」
ワイ「そんな時に便利そうや」

## 双方向バインディングでもしてみる
ワイ「ほな次はElmを使って、よくある**双方向バインディング**でもしてみよか」
ワイ「双方向バインディングいうんは」
ワイ「`input`タグにテキストを入力すると、その値が即座にJS側に渡されて」
ワイ「ページの他の部分のDOMにもその値が反映される、みたいなやつや」
ワイ「**Vue.js**とかでようやるやつやな」

ワイ「じゃあ今回は」

> ユーザーが`input`タグに数値を入力したら、
その数値が他のDOMにも表示される

ワイ「↑これを作ってみよか」

## どんな情報を管理していくかを`Model`として定義

ワイ「まず`Model`いう、**状態を表す型**を定義するんや」
ワイ「Elmは**静的型付言語**やからな」

ワイ「ほな、ユーザーが入力した数値は`userInputNumber`いう名前で管理していこか」

```elm
type alias Model =
    { userInputNumber : Int
    }
```

ワイ「`userInputNumber` という**整数**の状態を管理していきますよ、と」

ワイ「ユーザーの入力によって、整数の値が変わったら」
ワイ「それを表示内容に反映させてやるためやな」

ワイ「ほんで、次はその`Model`の初期状態を`init`いう名前で定義するんや」

```elm
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側で受け取る部分を書いていこか・・・」

**〜続く〜**

## 続編書いたで！
→ **[わざわざ学んでみたらElmのMaybe型が楽しかった
](https://qiita.com/Yametaro/items/7988b7dd2728cc2b9456)**

## 今回のコード
**[Ellie](https://ellie-app.com/5PVLMKZSXm3a1)**で見れるから好きにいじってみてや。

[^1]: 業務時間の10%（週4時間）を好きな研究・勉強に使っていいという制度