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) Unit
2 などと書いていたものが、単に 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 等逃げ道はいくらでもあると思いますが、ここでは触れません。 ↩