Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

Elmにおける型変数をもつデータ型の振る舞いについて

Last updated at Posted at 2016-12-07

この辺は、自分がよくわかっていない、自分でうまく説明できないことの1つ
型変数を持つデータ型は、Elmの定義では関数ではないけど、関数みたいな振る舞いをするよね、という話

Elmの型変数(type variables)

  • 小文字で表現される。一番目にするのは、ListList a
  • List aaはどんなデータ型でも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

everysecondsTimeモジュールで型定義されてる

second : Time
every : Time -> (Time -> msg) -> Sub msg

関数everyの型定義によると、2番目の引数はTime -> msgという関数として定義されてる
コンパイルを通すためには、Time.every second TickTickTime -> 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 aJustって何?ということに触れてる

...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では「関数は小文字始まり」というルールがあるので、関数ではない、とも言える

なんかこの辺りをうまく説明するものがある気がするが、とりあえず現時点ではこんな風に理解してる

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?