46
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Elmの型で読むReduxやVuexのアーキテクチャ

Last updated at Posted at 2020-01-05

はじめに

近年徐々に複雑になるwebフロントエンドの状態管理の仕組みとして、ReactやVue.jsといったwebフロントエンドフレームワークのお供にReduxやVuexと言ったライブラリを組み合わせて使うことが多いと思います。

それら二つのライブラリは、Elmという高品質webフロントエンド構築のための関数型AltJSが用いているThe Elm Architectureと呼ばれるアーキテクチャに影響を受けて作られました。

追記:
ReduxとElmの時系列はReduxの方が先であり、しかしながら状態のimmutableなどは影響を受けていることから、
現在の形のReduxはElmに影響を受けている所がある。
という表現が正しかったようです。
コメントありがとうございます。

参考
Vuexとは何か?|Vuex
reduxjs / redux

Elmの型システムや見た目は非常にリーダブルであり、型を読むだけでアーキテクチャの本質に近づけると思いますので、Elmユーザーだけでなく、Redux、Vuexがよくわからないと困っているユーザーの方でも読んでいただけたらと。

リーディング準備

Elmの型システムや見た目が非常にリーダブルと言われたところで、いきなり読み始めて分かるわけがないので馴染みが深いTypeScriptへ変換してElmの型を読む準備をしましょう。

この記事では関数の型を使うことによりアーキテクチャの説明をしますので、関数の型のみ見ていこう!

TypeScript
function increment(x: number): number {
    return x + 1;
}
Elm
increment : number -> number
increment x = x + 1

上の二つは全く同じ関数を定義していることになります
number型を引数にとってnumber型を返すincrement関数の定義は number -> number と書くことができる!

引数を二つ以上取る関数の型はこの様に書きます!

TypeScript
function add(x: number, y: number): number {
    return x + y;
}
Elm
add : number -> number -> number
add x y = x + y

なぜ(number, number) -> numberと書かないのかという疑問が湧くと思いますが、それは物凄い便利な機能と概念がバックに存在します。しかし本題からは外れますので、部分適用, カリー化という検索キーワードだけ置いておきます。

簡潔で読みやすい!準備完了!!

そしてこの記事で関数という言葉は同じ引数が入ってきたときに必ず引数以外の影響を受けずに同じ値を返す、数学的な純粋な関数を指します。

本題

フロントエンドは関数だ

まさにブラウザに映っているビューの状態はただの関数の戻り値でしかないというのがThe Elm Architectureの考え方であり、実装でもあります。

view関数の型
view : model -> html

model には実際には任意の型の任意の値が入っており、何かしらの値を引数にとるviewという巨大な関数が任意のhtmlを返すことによってフロントエンドが構築されます。

そして、modelの値が同じであれば常に同じhtmlを構築する関数こそがviewという関数になります。

The Elm Architectureの骨子

どんなElmプログラムも次の三つの要素に分解することができます。

  • Model — アプリケーションの状態
  • Update — 状態を更新する方法
  • View — HTMLとして状態を閲覧する方法

引用 - https://guide.elm-lang.jp/architecture/

既に登場したViewとModelによって実際にhtmlが構築されているのがわかりました。

しかしユーザーの操作に対して見た目が変わらないwebサイトなんて誰が作りたいでしょうか?

そこで、見た目の為の引数であるmodelの値を変更することにより、表示を変更することができます。

update関数の型
update : message -> model -> model

htmlから発射されたmessageとmodelを引数にして、新たな状態のmodelを返す関数となっています。

全体図

elm-architecture

引用 Programming Elm

この仕組みにより、モデルを引数にとってHTMLを構築するただの関数がいろいろな状態変化をすることができる様になりました!

実際の型

ここまで若干抽象的な話をしてきましたが、Elmで具体的な一番最小限のアプリケーション定義であるsandboxの実際の型を見てみましょう。

sandbox
sandbox :
    { init : model
    , view : model -> Html msg
    , update : msg -> model -> model
    }
    -> Program () model msg

initはブラウザで一番最初に表示した時の初期状態のmodelを定義します。
viewはmodelを引数にとって、Htmlを返す関数です。おまけ付きの様なmsgはユーザーが弄ったときにmsg型の何かしらをupdateに対して投げるよという意味です。
updateはmsgと現在のmodelの状態を引数にして、新たなmodelを生成して返す関数です。

これらを構造体のフィールドとして定義するとプログラムになるよ!という定義です。

本当にたったこれらのシンプルな3つのことを定義するだけで、全てのことが実現できてしまうアプリケーションが完成してしまうのがThe Elm Architectureであり、ReduxやVuexがやりたいことの本質なんですね。

まとめ

ReduxやVuexは非常に難しい名前の関数や使い道がよくわからない関数をたくさん定義して、何をしたいのかわからなくなることがありますが、結局やりたいことはmodelを引数にしてhtmlを返す巨大な純粋関数としてwebフロントエンドを定義してあげたいだけなんですね。

結局やりたいこと
view : model -> html

ちなみに、Elmという言語は非常に言語仕様が堅牢でコンパクトであり、不必要な機能を全て廃した非常に学びやすい言語です。
The Elm Architectureも非常にコンパクトで堅牢な為、非常に簡単に高品質なwebフロントエンドを構築することが可能になっていますので、ぜひ皆さんも型を読むだけじゃなくて試してみてくださいね。

46
23
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?