PureScript 0.12.0 で何が変わったか - Effect編
メモ
この記事は 2018/6/4 に Qiita へ投稿したものです。
このシリーズでは 2018/5/22 にリリースされた PureScript 0.12.0 で何がどう変わったかを紹介していきます。
今回は新しく登場した Effect の話です。
なおこの記事は PureScript に触れたことがある読者を想定しています。
PureScript 自体について知りたい場合には他の Qiita の記事や 実例によるPureScript などが参考になると思います。
Effect とは何か?
Effect は外部への出力といった native な作用を表す型コンストラクタです。
こんな感じで使います。
1 2 3 | |
Eff と何が違うのか?
0.11.7 までの PureScript では作用を記述するために Eff を使いました。
Eff では下記のようにどのような種類の作用を含むのかを row で記述します。
1 2 3 | |
Eff の定義は下記のとおりです1。
1 | |
一方 Effect には具体的な作用を表す row がなく、下記のような定義になっています。
1 | |
今まで ∀ eff. Eff (console ∷ CONSOLE | eff) Unit や ∀ eff. Eff (canvas ∷ CANVAS, console ∷ CONSOLE, dom ∷ DOM, exception ∷ EXCEPTION, random ∷ RANDOM, ref ∷ REF | eff) Unit2 などと書いていたものが、単に Effect Unit と書けるようになります。
なお Effect になってもコンパイル後の JavaScript のコードは Eff のときと変わりません。
Eff と同等の最適化(magic do)も行われます。
ちなみに Effect のサポート自体は破壊的な変更ではなく、今までの Eff もまだ使えます。
Effect 以外の変更も多いため新旧のバージョンを混在させるとまずコンパイルが通らないのですが、purescript-prelude 含む各種ライブラリを PureScript 0.11.7 時代のバージョンで統一すれば Eff もちゃんと動きます3。
なぜ Eff が Effect になったのか?
Eff ではその関数が持つ作用の種類を示したり、制限することができます。
しかし一方で慣れないと判りにくいですし、作用の種類を漏れなく記述する必要があります。
結局メリットに比べて面倒なことが多い、と多くの人が考えるようになったようです。
ここに至るまでの出来事を、自分が確認できた範囲で記載しておきます。
2016/8/12
PureScript 版 IO として purescript-io が登場しています。
このときの IO はそのままでは実行できず、IO → Aff → Eff と変換して使うようです。
2017/5/7
purescript/purescript-eff に Phil さんから下記 PR があります。
row なしの Eff a を定義した Control.Monad.Eff.Unrefined を追加するもののようです。
この PR はマージされないまま翌月に close されています。
自分の英語力ではその理由を充分に読み取れませんが、core ライブラリに入れるなら最適化されるべき、とか、row なしの Eff が row ありの Eff に依存する形になっているのが逆であるべき、とかそんな感じのようです。
2017/7/4
purescript/purescript-eff に下記 Issue が立ちました。
row なし Eff の方がシンプルで使いやすい、と考える人は多いようです。
2017/9/16
Philさんから Twitter でアンケートです。
結果は、賛成:50%、どちらとも言えない:36%、反対:14%、でした。
自分は当時このツイートを非公式アプリで読んだため、アンケートになっていたことに気付きませんでしたが。
2017/9/20
コンパイラ側の対応として purescript/purescript に下記 Issue が立ちました。
ここでは IO と書かれていますが名称についてはその後も下記 Issue で議論されています。
IO や Eff のほか Sync、Native 等いろいろ出ていましたが、結局早い段階から Phil さんが推していた Effect になったようです。
2018/5/22
Effect に対応した PureScript 0.12.0 がリリースされました。
-
ここに出てくる
Effectは kind であり、新しく追加された Effect とは別のものです。 ↩ -
こんなに書いているコードが実際にあるのかは不明です。 ↩
-
purescript-prelude と purescript-eff 程度なら問題ないですが、破壊的変更が多いため
Effectとは関係なく動かなくなるライブラリも多そうです。 ↩ -
unsafeCoerceEff 等逃げ道はいくらでもあると思いますが、ここでは触れません。 ↩