なのログ

だから見てて下さい・・・俺の・・・変身

基礎からわかる Elmを読んでいます(第2回)

第2回です。𝑻𝒉𝒆 𝑬𝒍𝒎 𝑨𝒓𝒄𝒉𝒊𝒕𝒆𝒄𝒕𝒖𝒓𝒆 (かっこいい書体)を学びました。
「とにかく Type Msg を用意してイベントごとに呼べ」は正しかったです。


正しかったですが、当然詳しい要素が色々ある。


こんにちは。こんばんは。第2回のわたしです。
前回から2週間。「間が空いてしまったな」と思ってやっています。
この本に関してはそれくらいの感覚で進めたいと思っているというおはなしでした。珍しい。

さて、前回は
「Elm書けるようになったな?(環境)」
「そして書けたな?(文法)」
という内容でした。

今回は「そんじゃElmの組み方を教えてやるよ」の話になります。即ち𝑻𝒉𝒆 𝑬𝒍𝒎 𝑨𝒓𝒄𝒉𝒊𝒕𝒆𝒄𝒕𝒖𝒓𝒆です。

ちなみに、範囲はCHAPTER 03スタートから半分くらいです。
わりと「とにかく Type Msg(略」だけでは済まないと感じた(当然)ので分けてしまいました。

では。はじまります!(今回も伝われ)

CHAPTER 03 SECTION 017 HTML

実質、Elmの関数を使ってHTML文字列を生成するだけの章です。
<a href ~を書きます。

そう、<a href ~を書いたんですよね。

main = 
     a [ href "https://elm-lang.org" ] [ text "Elm"]

読めますかね。

$ elm repl

> a
<function> : List (Attribute msg) -> List (Html msg) -> Html msg

a関数なんですけど。(属性のリストとHTML要素のリストが引数)

え、何、その発想は無かった。いや考えてみればそうするしかないんですけど。
2月の勉強会の時にも思った気はするんですが、何ですかねこれ。マジで発明では?

生成物はただの文字列とも言えると思うんですけど、
「それをHtml msg型として落とし込んでElmの動作として成立させてるの、HTMLへの理解度がエグくない????」という気持ちになっています。僕はその理屈についてなにもわかっていません。1歩目からアハ体験がすごい。

ちなみにこう、(JS動作も無いレベルで)静的なHTMLを生成したいだけであれば、
mainに対してHtml msgを作るプログラミングをすればええんやな~」という理解をしています。
そんな用途にElmを採用する奴おらんやろけども。

CHAPTER 03 SECTION 018 Elmアーキテクチャ

カウンターをつくりました。

f:id:nanoyatsu:20200809100549p:plain
こういうやつ。

早速mainに入れるものがHtml msgじゃなくなってウケましたが、例のアレが出て参りました。

type Msg
    = Increment
    | Decrement

type Msg !!!!!!11

書き進めますとね、いやもーマジで「例のアレ」なんですよね。
TEAの構成要素としてView, Model, Updateの定義があると教わるわけですが、
その中からUpdateを切り抜いてベタっと貼っときましょう。

update : Msg -> Model -> Model
update msg model =
    case msg of
        Increment ->
            model + 1

        Decrement ->
            model - 1

Msg(操作)とModel(今の状態)を受け取って、Model(次の状態)を返すんですよ。
妥当オブ妥当。こんなんまさしく状態遷移。状態遷移図。

ちなみにMsgはボタンを押したときに発行されます。
(button [ onClick Increment ] [ text "+" ] とか書いています)

いやあ、これはTEA完全に理解しましたね・・・。(定期)

幕間

SECTION 019はこれでした。
f:id:nanoyatsu:20200809102139p:plain

SECTION 020はこの後の拡張(コマンド、サブスクリプション)の説明(2ページ)でした。

CHAPTER 03 SECTION 021 コマンド

HTTPリクエストを叩きました。
f:id:nanoyatsu:20200809103413p:plain

これまで、画面の要素を操作された時にMsgの発行をしていたわけですが、
「非同期タスクが裏で走った時の画面更新もしたくね?」というニーズに応える回です。

そしてそれをコマンドと呼ぶようです。
ここでも、Update関数を貼りましょう。

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Click ->
            ( model, Http.get { url = "https://api.github.com/repos/elm/core", expect = Http.expectString GotRepo } )

        GotRepo (Result.Ok repo) ->
            ( { model | result = repo }, Cmd.none )

        GotRepo (Result.Err err) ->
            ( { model | result = Debug.toString err }, Cmd.none )

返り値がModelCmdのタプルです。
時限爆弾抱えさせながら返してる感じだと思います。(ほんとか?)

・・・なんか不安なので、ちゃんとした説明も引用して書いておきます。

▶コマンド(Command)
ランタイムに何らかの処理を実行させ、その結果をメッセージとして受け取ります。

まあこう、「おわったらこれ呼んでや」ってコールバックの代わりにMsgを伝えておく感じですね。

つづく

というわけで、The Elm Architectureさんに足を踏み入れました。

ぶっちゃけ完全な革新性みたいなものがあるかというとそれほどでもないと思うんですが、
これをルールとして言語レベルで強制することで圧倒的な強さになるんだなという感想です。

コマンドのくだりとか、Androidでいうたら
startActivityForResult()onActivityResult()ですからね。
ゴチャゴチャした使い方したらマジでクソ嫌われるやつ。

そこに対して、型安全性と強いルールを盛り込むことで、
人間の考慮ポイントを減らすことに成功しているので見事です。

あと、なんだか読み進めていて、
GUIに本質的に必要なものとは」みたいな考えが整理されている気がしています。

もしかして本質じゃなかったとしても、既に整えられたElm思想をなぞることで整った開発を身に着けていけるといいんですけど。
つまり本業のアプリの開発にも良い影響が出ればなあ、みたいな。


さて最後ですが、記事にしてみたらかなり中途半端なところで切ってしまったなと感じています。
(このあとコマンド結果のJSONをいい感じにしたりサブスクリプションの方をやったりする)

次回CHAPTER 03を終えるつもりで、04までがたくさん手を動かすメニューです。
05は設計について、06はコミュニティとかライブラリを組む時とかのお話。
なんかたぶんスピード出して進めるのはCHAPTER 04までかなと感じています。
それ以降はブログに書くかもあやしめですかね。

というわけで、8月中にCHAPTER 04までいけると嬉しいかなあというくらいです。
個人的な家の引っ越しとかも今月はあるんですが。まあやれるようにやっていきます。

ではまた✋