- Elm Advent Calendar 2016 - Adventar 7日目
- Elmの勉強の記録
- Elm in Actionの3章を読んで、現時点での自分の頭の整理
この辺は、自分がよくわかっていない、自分でうまく説明できないことの1つ
型変数を持つデータ型は、Elmの定義では関数ではないけど、関数みたいな振る舞いをするよね、という話
Elmの型変数(type variables)
- 小文字で表現される。一番目にするのは、
ListのList a型 -
List aのaはどんなデータ型でもOK- なので、数値のリストは
List Intという風にもかける
- なので、数値のリストは
TodoMVCのElm版をみると、
port setStorage : Model -> Cmd msg
のCmd msg
viewInput : String -> Html Msg
viewInput task =
...skip...
のHtml Msg
onEnter : Msg -> Attribute Msg
onEnter msg =
...skip...
のAttribute Msgなどの使ってるモジュールで定義されたデータ型に型変数を持つものや、
type Msg
= NoOp
| UpdateField String
| EditingEntry Int Bool
| UpdateEntry Int String
| Add
| Delete Int
| DeleteComplete
| Check Int Bool
| CheckAll Bool
| ChangeVisibility String
のようにtype alias、union typesを使って定義されたものもある
型変数をもつデータ型は「変形」してつかわれる
type aliasや、union typesを使った型定義をしてる行ってる箇所でみかける。
例としてSVG時計のサンプルから、コード例をとってくると
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every second Tick
ここのTickがもともとの型定義から変形されたもので、
type Msg = Tick Time
everyやsecondsはTimeモジュールで型定義されてる
second : Time
every : Time -> (Time -> msg) -> Sub msg
関数everyの型定義によると、2番目の引数はTime -> msgという関数として定義されてる
コンパイルを通すためには、Time.every second TickのTickがTime -> msg型の関数でなければならない
> type Msg = Tick Time.Time
> Tick
<function:_user$project$Repl$Tick> : Time.Time -> Repl.Msg
Repl(elm-repl)で確認すると、Msg型の型定義から派生的にTickの型定義が得られて、それがここで欲しい型(Time -> msg)であることが確認できる
- replでは、関数がqualified styleなので、
Time.やRepl.などのモジュール名が省略されずに出力されてる
関数の部分適用も型の変形
部分適用した関数の型定義は、元の関数の型定義を変形して得られる形をしてる
StringモジュールのpadLeftは引数が3つ登場する
padLeft : Int -> Char -> String -> String
> String.padLeft 9 '.' "not"
"......not" : String
これを部分適用すると
> String.padLeft 9 '.'
<function> : String -> String
となり、部分適用された式が評価されると、Stringが引数で戻り値も引数の関数がえられる
-
padleft Int Charは、String -> String型の関数 - この関数の型定義は、関数
padLeftの型定義から派生的に作られてる
'"JUST" IS A FUNCTION'
- Elm in Action MEAP V03, p.73
type Maybe value
= Just value
| Nothing
Maybe型は、union typeを使ってるんだが、そこで出てくるJust aのJustって何?ということに触れてる
...whereas Nothing is a Maybe value, Just is a function that returns a Maybe value
> Nothing
Nothing : Maybe.Maybe a
> Just
<function> : a -> Maybe.Maybe a
> Just "dance"
Just ("dance") : Maybe.Maybe String
このへんは「関数みたいなもん」くらいのニュアンスで読んだ
型変数を持つデータ型は関数なのか?
- 関数っぽく振舞っている、とは言える
- いわゆる関数の式の変形ができるので
- しかしElmでは「関数は小文字始まり」というルールがあるので、関数ではない、とも言える
なんかこの辺りをうまく説明するものがある気がするが、とりあえず現時点ではこんな風に理解してる