【elm】2019年にわざわざ学ばなくてもいい言語でTodoアプリを作る

「2019年にわざわざ学ばなくてもいい言語」 が発表されました。

https://www.codementor.io/blog/worst-languages-2019-6mvbfg3w9x

CoffeeScriptを抑えて堂々の1位はElmとなりました。

残念なニュースではありますが、個人的には好きな言語ですのでElmで簡単なTodoリストアプリを作成してみます。

2019/07/01更新

コメントでご指摘頂きました。ありがとうございます!
モジュールを分割せず1ファイルに修正し、GitHubにpushしましたのでこちらを参照するようにしてください。

ABAB↑↓BA より:
2019年6月28日 9:35 PM
このモジュールの分割の分け方は公式ガイドで悪手とされています。1ファイルにまとめていただけると、混乱する方が減って嬉しいかもしれません。
https://guide.elm-lang.jp/webapps/modules.html

Elmとは

Elmは、コンパイルすることでWebアプリケーションを作成することができる純粋関数型言語です。

The Elm ArchitectureというアーキテクチャでWebアプリをModel-View-Updateという形にパターン化しています。

例えばユーザーのInputによって画面が更新されるWebアプリはThe Elm Architectureでは以下のようにパターン化されます。

環境構築

Elmのインストールはnpmで行います。

$ npm i -g elm

これだけでelmのインストールは終わりです。

次に作業ディレクトリを作りましょう。 ディレクトリを作成しその中でelm initコマンドを実行します。

$ mkdir todo & cd todo
$ elm init
Hello! Elm projects always start with an elm.json file. I can create them!
Now you may be wondering, what will be in this file? How do I add Elm files to
my project? How do I see it in the browser? How will my code grow? Do I need
more directories? What about tests? Etc.
Check out <https://elm-lang.org/0.19.0/init> for all the answers!
Knowing all that, would you like me to create an elm.json file now? [Y/n]:
Okay, I created it. Now read that link!

以下のようにelm.jsonとsrcディレクトリが作成されれば完了です。

.
├── elm.json
└── src

この状態でelm reactorコマンドを実行してみましょう。

$ elm reactor
Go to <http://localhost:8000> to see your project dashboard.

elmのWebサーバが起動したらhttp://localhost:8000にアクセスするとElmの画面が表示されます。

実装

The Elm ArchitectureではModel-View-Updateの形でパターン化されますのでsrcディレクトリ以下にそれぞれのファイルと、エントリーポイントとなるMain.elmを作成します。

$ touch Main.elm Model.elm View.elm Update.elm
./src
└── Main.elm

Model

まずはModelから作成します。

Todoデータを格納するTodo型を作成します。 Todo型はString型のタイトルと詳細を持ちます。

type alias Todo =
  { title : String
  , description : String
  }

Modelは複数のTodoデータを持ちますのでList型のtodosを宣言します。

type alias Model =
  { todos : List Todo }

初期値を設定します。 Todoリストの初期値は空にしたいので空のリストを設定します。

init : Model
init =
  { todos = [] }

さらにTodo項目を追加するためのメッセージ(Msg)も作成します。

type Msg = Add

最終的にModelはこのようになります。

type Msg = Add
type alias Todo =
  { title : String
  , description : String
  }
type alias Model =
  { todos : List Todo }
init : Model
init =
  { todos = [] }

Update

UpdateはMsgとModelを受け取って新しいModelを返します。

これはReduxのReducerがactionとstateを受け取って新しいstateを返す動きに似ていますね。

update : Msg -> Model -> Model

AddイベントはModelにTodo型のデータを追加します。

今回はサンプルなのでタイトルが「Todoタイトル」、詳細が「Todo詳細」となるTodo型のデータをModelに追加するようにしています。

update : Msg -> Model -> Model
update msg model =
  case msg of
    Add ->
      { model | todos = ( Todo "Todoタイトル" "Todo詳細" ) :: model.todos }

View

次にViewを作成します。 Todoリストの項目をテーブルで表示しましょう。

import Html exposing (..)
import Html.Events exposing (onClick)
view : Model -> Html Msg
view model =
  div []
      [ viewTable model.todos
      , button [ onClick Add ] [ text "Add" ]
      ]
viewTable : List Todo -> Html Msg
viewTable todos =
  table []
        [ thead []
              [ th [] [ text "Title" ]
              , th [] [ text "Description" ]
              ]
        , tbody [] ( List.map viewTr todos )
        ]
viewTr : Todo -> Html Msg
viewTr todo =
  tr []
    [ td [] [ text todo.title ]
    , td [] [ text todo.description ]
    ]

viewTebleはModelのtodos(Todoリスト)を受け取ってテーブルを返す関数です。

elmではHaskellのような記述で関数定義を行います。 関数名 : 引数 -> 戻り値の形になります。

Main.elm

最後にmain関数を実装します。

import Browser
main : Program () Model Msg
main =
  Browser.sandbox
  { init = init
  , update = update
  , view = view
  }

これでTodoリストの完成です。

再度elm reactorを起動しブラウザで確認しましょう。 (http://localhost:8000/src/Main.elm

ボタンを押すとテーブルにTodoが追加されるはずです。

まとめ

今回はElmで簡単なTodoリストを作成しました。

実務で使用するのはまだ難しい印象ですが実装していて楽しい言語ですので冒頭のような暗い話題ではなく、明るい話題でWeb界隈を盛り上げて欲しいものです。

今回使用したソースコードは以下になります。

https://github.com/aizulab-igarashi/todo_elm

1個のコメント

コメントを残す

メールアドレスが公開されることはありません。*がついている欄は必須項目です。

日本語が含まれない投稿は無視されますのでご注意ください。