Edited at
ElmDay 18

Elmの型システムを少しだけ覗いてみる

More than 1 year has passed since last update.


要約

大体HM型システム。


導入

Elm Advent Calender その1 18日目です。前日は@ebiryu さんの[Elm] elm-touch-events使ってみた

でした。Elmでタッチイベント、熱い。

Elmに関しては初心者でちょっとしたアプリケーションを作ったくらいなのだが、Elm Advent Calenderを書けという関係各所(一人)からの圧力がかかってので初心者ながらElmの型システムに関してわあkったことについて書いてみる。最後の方Effect Managerの話ししてるけども。

ざっとelm-compilerのコードをわかんねぇわかんねぇ言いながら読んだだけなのでお手柔らかに。


基本の型

他の言語に比べてわりかしプリミティブ型は少ない。

ここらはさくっとくぐり抜けていこう。


数値型

IntFloatがある。

1 : Int      -- 型注釈は`:`

2.5 : Float

numberは数値型をすべてを引き受ける型として扱える。


文字と文字列

CharStringがあるよ!

'a' : Char

"elm" : String

余談だが、Haskellと同様シングルクォートでChar、ダブルクォートでStringだ。


論理型

当然Boolもあります。

True : Bool

False : Bool


List

[1, 2, 3, 4] : List (Int)


Tuple

(1, 'a') : (Int, Char)


Record

myRecord = { style = "Blue"

, number = 1
, isCool = True
}


Union

直和型とは本質的に違うので注意。

type Answer = Yes | No

type Answer' a = Yes | No | Other a -- このように型変数を使うことも可能


直積型

type Position = Position Int Int


Unit

型界のNull(?)、Unit型()もある。


関数型

引数の型 -> 返り値の型で関数の型を表す

add : Int -> Int

add x y = x + y

ちなみに(->)は左結合の型演算子だよ。


多相と型推論

パラメータ多相1は存在するので、型変数を用いた関数を書くことができる。

add : a -> a

add x y = x + y

とは言え残念ながら、高階多相は無い、アドホック多相もない。2

なので、アドホックな多相を行いたければそういった感じの関数をJSで書くしか無い。3

アドホックな関数を実装するために、number,appendable, compableといった型クラスもどきがプリミティブに存在している。

型推論はHindle-Milner型推論を使っているので、型を省略しても大体なんとかしてくれる。


Effects型

Elmの目玉とも言えるEffectsまわりだが、とりあえず純粋でない計算を行いたいのであればEffects型を返しておけというゆるふわ感がある。このゆるふわな感じのお陰でHaskellほど型パズルに苦しむ必要がない。

Effects型自体はPortManagerに大別されるようだ。

Portの場合はそのままElmのJavaScriptのコードジェネレータに渡され、プログラムに組み込まれる。

ManagerCmd, Sub, Fx4(CmdとSubを合わせたもの),Task,Router`を基本的な型としており、型推論や型検査は対応するEffect Managerのパッケージ名とEffects自体が持ってる値を型として扱うことで実現している。

型検査後はEffect ManagerをJavaScriptに変換した後、それを参照できるような形で組み込んで他のコードをJavaScriptに変換しているようだ。


まとめ

見た感じ型システムはHaskellをもっと簡単にしたようなものなので、特につまずくことはないなと感じる。

厄介なのはEffect Managerあたりで、とりあえずは別々にJSに変換してるだけのようだが……

Effect Managerを作ってみて生成されたJSのコードを見てさらに深く探っていきたい。5

明日は@4245Ryomt さんのstreamライブラリについて

楽しみだ。





  1. 早い話がlet多相 



  2. 部分型多相はUnion型とか構造的部分型使えばできそうなんだけどなんかうまくいかなかったので誰か頼む。 



  3. 一生懸命自分で型クラスを実装するという手もある。彼のように 



  4. elm-compilerのコード内のみでの呼称 



  5. そんなことしてないでなんか作れ