- 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では「関数は小文字始まり」というルールがあるので、関数ではない、とも言える
なんかこの辺りをうまく説明するものがある気がするが、とりあえず現時点ではこんな風に理解してる