日本人の朝食といえば白米
犬といえば柴犬
日本の山といえば富士山
プログラミング言語の学習といえば…?
そうだね、TODOリストだね
なのでTODOリスト作ります
やること
- [x]
List
でTODOリストを保持する - [x]
List
をHTML
に吐き出す - [x]
input
に入力した値をbutton
を押すことでリストに追加 - [ ] 無名関数の関数化
せっかくだからやったほうが良いと思う - [ ] 空のTODOは追加できないようにする
- [ ] TODO横に削除ボタンを作成、押したら消せるように
- [ ] TODOをダブルクリックで
input
化して更新できるように - [ ]
localstorage
に保存できるようにする - [ ] 見た目オシャンティーにする
やったこと
ベースとなるレコードの定義
type alias Model = { todoList : List String , inputText : String } initialModel : Model initialModel = { todoList = [ "a", "b", "c" ] , inputText = "" }
type alias Model
todoList
表示するTODOの一覧
追加、削除、更新されたりする
これを参照してTODOを表示するようにするinputText
追加用のinput
の内容を受け取る
TODOリストの追加に使う
initialModel
初期化しているだけ
適当なTODOリスト表示用のデータと空の入力欄データを用意
動作(Msg
)の定義
type Msg = Add | UpdateTextField String
Add
TODOの追加
inputText
をそのままtodoList
に追加するつもりなので引数なしUpdateTextField String
inputText
の更新
onInput
からString
の引数で入力値が渡ってくる
update
update : Msg -> Model -> Model update msg model = case msg of Add -> { model | todoList = model.inputText :: model.todoList } UpdateTextField txt -> { model | inputText = txt }
Add
追加ボタンを押したタイミングでinputText
に入っている値を
TODOListに追加している
todoList = model.inputText :: model.todoList
model.inputText :: ["a", "b", "c"]
で配列の先頭に追加して
それをtodoList
に代入している
他言語だと大体末尾に追加するから何だか新鮮
docs/syntax
UpdateTextField
inputText
をフィールドの値で更新している
onInput
なので入力する度に発火している
物凄いイベント量だけどonBlur
とかのほうがいいのかな?と思っている
showTodoList
showTodoList : List String -> Html msg showTodoList todoList = todoList |> List.map (\todo -> li [] [ text todo ]) |> ul []
今回の目玉。todoList
を使って以下のリストを作る
<ul> <li>a</li> <li>b</li> <li>c</li> </ul>
引数はString型のList
で戻り値はHtml msg
戻り地をそのままviewに渡してHTML
が描画できる
|>
パイプ演算子
左から右に流れるので感覚的に慣れていて読みやすい(LInuxの|
っぽい)
js
の[1,2,3].map(val => val * 1);
みたいな関数っぽく読める
docs/syntax
|> List.map (\todo -> li [] [ text todo ])
List.map
関数でtodoList
内のデータに対して
無名関数(\todo -> li [] [ text todo ])
を1つずつ適用する
\
から始めると無名関数が作れて()
で無名関数の範囲を指定できる
以下のようなListが生まれる
[ li [ text "a" ] , li [ text "b" ] , li [ text "c" ] ]
|> ul []
ul []
の後ろに上で作ったli
の塊をくっつける
するとこうなる
ul [] [ li [ text "a" ] , li [ text "b" ] , li [ text "c" ] ]
見覚えのある形
そう、Html
モジュール全部触ろうで散々書いたHtml
のタグの形である
view
, showTodoList model.todoList
先程作ったul [] [ li [] [] ]
を作るshowTodoList
を読んでいる
showTodoList
の引数はList String
なのでTODOリストの元となる
model.todoList
を渡している
まとめ
- パイプ演算子が全く慣れない
関数全くわからん さっぱりだ
でも面白い。もっと理解してゴリゴリ書けるようになりたい - 間違いをコンパイラが丁寧に全部教えてくれた
- 関数の引数と型あってないぞ!
- List (Html msg)じゃなくてHtml Msgくれ! などなど。学習の手助けをひたすら健気にしてくれてありがたい
- ネットに転がってるサンプルの質が高い(気がする)
javaScript
だとググったらすぐ出るんだけど、レガシーだったり変なコードだったりすることが多々ある
Elm
は不思議とそういうコードに今のところであってない気がする
(無知で良いコードと悪いコードの区別がついていない説もある)
おまけ
List String
からHtml
に変換するとこ
stackoverflow.com
ググったらこんなのが出てきて混乱した
renderList : List String -> Html msg renderList lst = ul [] (List.map (\l -> li [] [ text l ]) lst)
renderList : List String -> Html msg renderList lst = lst |> List.map (\l -> li [] [ text l ]) |> ul []
renderList : List String -> Html msg renderList lst = lst |> List.map (li [] << List.singleton << text) |> ul []
パイプ演算子しかわからない
ぜんぜんわからない 俺たちは雰囲気でElm
をやっている
\
\
はλ
っぽいって話がガイドに書いてあった
言語の基礎 · An Introduction to Elm
バール片手に暴れまわる物理学者を思い出しました
HALF-LIFE3まだ?