ちょっと混乱したので自分用のメモです。
ElmはHaskellと異なりmap
はそれぞれの型に対して個別に定義されている。
Html型に対するmap
は次の仕様。
map : (a -> msg) -> Html a -> Html msg
- Htmlによって生成された(附帯した)メッセージを変換する関数
- 第1引数は、ある型の値を別の型(メッセージに使う型)に変換する純粋関数
- 第2引数はHtml型の何らかの値
- 戻りは第2引数のメッセージ部分を第1引数の関数で変換した結果となる
Haskellのmapで、こういうことをしているのと同じ
>>> map digitToInt ['1','2','3']
[1,2,3]
-- (Char -> Int) -> [Char] -> [Int]
ここでリスト([]
Elm風に書くならList
)がHtmlに相当する
https://package.elm-lang.org/packages/elm/html/1.0.0/Html#map の例では
type Msg = Left | Right
view : model -> Html Msg
view model =
div []
[ map (\_ -> Left) (viewButton "Left")
, map (\_ -> Right) (viewButton "Right")
]
viewButton : String -> Html ()
viewButton name =
button [ onClick () ] [ text name ]
- viewButton関数はHtmlを返すが、メッセージは
()
(空のイメージ) - この
Html ()
の()
をview関数内で無名関数をmapしてMsgに変換している。
要するにメッセージを特定しない汎用のボタンを描画する関数を作っておいて、あとから生成したいメッセージをmapするという使い方か。
引用元には「これはあまり頻繁には役に立ちません。」って書いてあるんですが(笑)、Elmとしては例のケースではわざわざmap使うより
view model =
div []
[ button [ onClick Left ] [ text "Left" ]
, button [ onClick Right ] [ text "Right" ]
]
と書くほうがシンプルで分かりやすい、ってことなんだろう。
もう少し複雑なものを書くようになると便利な局面が出てくるのだろうか。
使いどころを理解したら追記します。