このシリーズでは 2018/5/22 にリリースされた PureScript 0.12.0 で何がどう変わったかを紹介していきます。
今回は新しく登場した Effect
の話です。
なおこの記事は PureScript に触れたことがある読者を想定しています。
PureScript 自体について知りたい場合には他の Qiita の記事や 実例によるPureScript などが参考になると思います。
Effect とは何か?
Effect は外部への出力といった native な作用を表す型コンストラクタです。
こんな感じで使います。
hello ∷ Effect Unit
hello = do
log "Hello World!"
Eff と何が違うのか?
0.11.7 までの PureScript では作用を記述するために Eff を使いました。
Eff
では下記のようにどのような種類の作用を含むのかを row で記述します。
hello ∷ ∀ eff. Eff (console ∷ CONSOLE | eff) Unit
hello = do
log "Hello World!"
Eff
の定義は下記のとおりです1。
foreign import data Eff :: # Effect -> Type -> Type
一方 Effect
には具体的な作用を表す row がなく、下記のような定義になっています。
foreign import data Effect :: Type -> Type
今まで ∀ 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 がリリースされました。