ワイのElmデビュー【前編】

「[**純粋関数型言語と参照透過性**](https://qiita.com/jzmstrjp/items/1de3c2b76b8a4dc2d30d)」の続きやで。
別に前の記事は読まんでも大丈夫やけどな。

# いつものブラック会社にて
ワイ「あー」
ワイ「今日は**やることない日**やな」

社長「（**そんな日はない**で・・・）」

ワイ「**Twitter**でもしよか」
ワイ「・・・あっ、せや！」
ワイ「昨日**ハスケル子ちゃん**が言うてた**Elm**いう言語でも勉強してみよか！」

# Elmのお勉強開始
ワイ「**Elm-jp**いう日本のコミュニティがあって、その人らのサイトに**公式ドキュメントの日本語版**があるらしいんや」
ワイ「[**このサイト**](https://elm-lang.jp/)やな」
ワイ「お、なんや**可愛いヤギさん**の写真が出てきたで」
ワイ「これは**違うサイト**を開いてもうたかな？」
> **Elm-jp は日本を活動拠点とする、Elmユーザーの集まりです。**

ワイ「いやいや、このサイトで合ってるみたいや・・・」
ワイ「ほな[**公式ドキュメント翻訳プロジェクト**](https://guide.elm-lang.jp/)ってやつを読んでいこか」
ワイ「・・・ふむふむ」
ワイ「なんか**翻訳文なのにムッチャ読みやすい**な」
ワイ「**もともと日本語で書かれてる文章みたい**や」
ワイ「これはありがたいこっちゃで・・・」

ワイ「なになに」
ワイ「GitHubから**サンプルコード**をクローン出来るんやな」
ワイ「早速クローン、と」
ワイ「おお、色んなサンプルコードが入っとるな」
ワイ「**シンプルなコード**やから**ザコーダー**のワイでもけっこう読めるで」

# なんか作ってみる
ワイ「ほな、サンプルコードを元に」
ワイ「何か簡単なものでも作ってみよか」
ワイ「・・・よっしゃ、**ワイが敵と戦うゲーム**でも作ろか」
ワイ「**ワイ**と**敵**がおって、**攻撃しあって体力を奪い合う**ゲームや」

ワイ「ほな、**ワイっていうキャラクター**と**敵っていうキャラクター**の」
ワイ「体力とかそういう**状態**を管理していかなあかんわけや」

ワイ「Elmには**再代入**いう概念がないらしいけど、そんなんでどうやってキャラクターの**状態を管理**していくんやろ？」
ワイ「キャラクターは攻撃を受けたらHPが減るやん？」
ワイ「その**状態変化**を、**再代入なしに**どうやってプログラミングすんねやろ」
ワイ「ハスケル子ちゃん曰く、そこはやってみんと分からんらしいから、とりあえず作っていこか」

ワイ「Elmは**静的型付き言語**やから、まずは型の定義をキッチリするとええらしいな」
ワイ「やってみよか」
ワイ「ほなまずは、**状態**を意味する**Model型**を定義すればええんやな」
ワイ「**ワイっていうキャラ**と**敵っていうキャラ**の**状態を管理**していきますよ、と」

```elm
type alias Model =
    { wai : Character
    , teki : Character
    }
```
ワイ「こうやな」

ワイ「そんで、次はその**キャラクターってのは何なのか**を定義するで」
ワイ「せやから、**Character型**っていう**自作の型**を定義すんねや」

```elm
type alias Character =
    { name : String
    , hp : Int
    , offensivePoint : Int
    }
```

ワイ「**キャラクター**いうのは、**名前**と**HP**と**攻撃力**を持ってるやつですよ、と」
ワイ「こうやな」

ワイ「なんか**設計書を書いてるみたい**やな」

ワイ「次は**Modelの初期状態**を**init**っちゅう値として設定すんねやな」

```elm
init : Model
init =
    { wai =
        { name = "ワイ"
        , hp = 1000
        }
    , teki =
        { name = "敵"
        , hp = 2000
        }
    }
```
ワイ「waiの表示名は**ワイ**で、HPは**1000**」
ワイ「tekiの表示名は**敵**で、HPは**2000**」
ワイ「これでよし、と」
ワイ「**保存**や」

ワイ「お、**コンパイルエラー**が出てもうた」

> **型の不一致**
> ヒント：offensivePointがないように見えます。

ワイ「おう、そういえばまだ**攻撃力の値を書いてなかった**わ」
ワイ「なるほど、さっき**定義した型のとおりにコード書かんと**怒られるんやな」
ワイ「**親切**なもんやで。」
ワイ「これが**静的型付き言語**の**恩恵**やな」
ワイ「設計書の通りにコーディングせんかったら怒ってもらえるなんて、ワイのようなザコーダーにもぴったりや」

# ビューを書く

ワイ「ほんで次は、**view関数**の中にHTMLのタグみたいなんを書くんやな」
ワイ「これはちょっと書くの面倒そうやから」
ワイ「**HTML**から**Elmのコード**に**変換**してくれる**Atom拡張機能**を使って変換や」

```html
<ul>
    <li>
        <div>ワイ</div>
        <div>HP: 1000</div>
        <button>攻撃</button>
    </li>
    <li>
        <div>敵</div>
        <div>HP: 2000</div>
        <button>攻撃</button>
    </li>
</ul>
```

ワイ「これが」

```elm
    ul []
        [ li []
            [ div [] [ text "ワイ" ]
            , div [] [ text "HP: 1000" ]
            , button [] [ text "攻撃" ]
            ]
        , li []
            [ div [] [ text "敵" ]
            , div [] [ text "HP: 2000" ]
            , button [] [ text "攻撃" ]
            ]
        ]
```

ワイ「こう変換されるんや」

ワイ「（ちなみにこのAtom拡張機能は[**ワイが作ったんや**）](https://qiita.com/jzmstrjp/items/f35cf85c277d035b247f)」
ワイ「（Elmほぼ書いたこと無いのにな・・・）」
ワイ「（**設定ムチャクチャ**や・・・）」

ワイ「ほんで、名前とかHPを**動的に表示**せんといかんから」

```elm
text "ワイ"
```

ワイ「の部分は」

```elm
text model.wai.name
```

ワイ「に変更や」
ワイ「あと、」

```elm
text "HP: 1000"
```

ワイ「の部分は」

```elm
text ("HP: " ++ model.wai.hp)
```
ワイ「に変更やな」
ワイ「おっと、また**コンパイルエラーが出た**で」

> **型の不一致**
String.fromIntを使って文字列に変換してみますか？

ワイ「なるほど、**HP**は数値やから文字列に変換してから表示せなあかんのか」
ワイ「相変わらず**エラーが親切**やで」

```elm
text ("HP: " ++ String.fromInt model.wai.hp)
```

ワイ「こうやな」

ワイ「ほんで、**攻撃ボタンをクリック**すると」
ワイ「ワイの攻撃力の分だけ**敵のHPが減るように**したいんや」
ワイ「それはどうすればええねや？」

# ケル子ちゃんに聞いてみる

ワイ「お〜い、ハスケル子ちゃん」

ハスケル子「はい」

ワイ「うーんと・・・」
ワイ「**攻撃したらHPを減らしたいんや**」

ハスケル子「・・・」
ハスケル子「**なんの話ですか**」
ハスケル子「**よくそれで伝わると思いましたね**」

ワイ「ごめん、うまく説明できひんねや・・・」

ハスケル子「**もういいです**、コード見ます」

ワイ「あっでも、もうすぐ定時やから明日でええで」

ハスケル子「大丈夫です。**本気**出してすぐ終わらせます」
ハスケル子「ちょっと、**これ**外しますね」

ワイ「お、おう」
ワイ「（やっぱり**両腕に3つずつApple Watch**を着けてると邪魔なんやな・・・）」

ハスケル子「よいしょ、っと」

**ガチャン！！**（床が砕ける音）

ワイ「**！？**」
ワイ「（おいおい、今まで**こんな重いApple Watch**を着けてコーディングしとったっちゅうんか・・・！？）」

ハスケル子「急いでコード読みますね・・・」

ワイ「（**は、速い！**）」
ワイ「（凄い**眼球の動き**や・・・！）」
ワイ「（これが**本来の力を解放した**ハスケル子ちゃんなんか・・・）」

社長「（**Apple Watch関係あらへん**）」
社長「（ていうかハスケル子ちゃん、**平気な顔して会社の床を砕きよる**な・・・）」

ハスケル子「あ、この部分ですね」
ハスケル子「ワイさんの攻撃ボタンに**onClick属性**をつける感じで、値は**WaiAttack**とかってしておけば、**クリックと連動**して**キャラクターの状態を更新**できます」

```elm
button [ onClick WaiAttack ] [ text "攻撃" ]
```

ハスケル子「こうですね」
ハスケル子「あとは**HPを減らす処理**を**update関数**の中に書いてください」

ワイ「おう、おおきにやで」

ワイ「**update関数**の中で、」
ワイ「**攻撃ボタンクリック後の状態**・・・つまり**新しいModel**がどんな感じになるんかを書けばええんやな」

ワイ「ほな、**ワイが攻撃した場合**は**敵のHPを減らす**・・・」
ワイ「逆に、**敵が攻撃した場合**なら、**ワイのHPを減らす**・・・と」

ワイ「それを書いていこか・・・」

**〜後編に続く〜**

# 後編書いたで
[**ワイのElmデビュー【後編】**](https://qiita.com/jzmstrjp/items/360c7e1e4fa2c6d7b7b4)

# 追記: おすすめ記事
[**Elmで体験する関数型言語の面白さ**](https://qiita.com/pxfnc/items/542e0f6705182a9f93ad)
後編の前にこの記事を読んどくとええかもしれん。