Haskell
Monad
extensible-effects
freer-effects
free-monad

Freer Effectsが、だいたいわかった: 0. 導入

Freer Effectsが、だいたいわかった: 0. 導入

はじめに

Extensible Effects (hackage: extensible-effects)の改良版であるFreer Effects (hackage: freer-effects)が、だいたいわかったので、解説する。

端的に言えば

Extensible Effectsとは、(1)本質的にはFreeモナドである。(2)存在型による、拡張可能な型をFreeモナドによって、モナドに変換している。ただし、それだけだと、あまりに自由すぎるので、(3)型により不適切な操作を禁止している。

この、みっつがExtensible Effectsの本質である。

想定読者

  • Haskellの初歩的なところは、だいたいわかる
  • ファンクタについても、だいたいわかる
  • モナドについては、だいたい理解した
  • GHCの言語拡張も、すこしは使ったことがある
  • モナド変換子は、使ったことがある
  • コードを読むのが好き

記事の概要

Freer Effectsを、みっつの本質と、ひとつの効率化としてとらえ、ひとつずつ追加して実装していくことで、コードレベルでの理解を目指す。全部で16部構成とする予定であり、現在は第11部の途中まで書いた。

まずは、完成させることを目指すので、多少、荒削りになるかもしれない。まちがいや、わかりにくいところがあったら、コメントでよろしくおねがいします。

気ままに書いていきますので、完成まで気長におつきあいいただけると、幸いです。

Extensible Effectsとは

モナド変換子は、モナドを層状に積み重ねる。それに対して、モナドを混ぜ合わせるのがExtensible Effectsだ。モナド変換子とくらべて、実行効率がいい。また、階層関係を意識しなくていいので、コードが書きやすい。

Freer Effectsとは

Extensible Effectsを改良したもの。効率がより向上し、かつ、コードが簡潔になっている。

Extensible Effectsの本質は、みっつ

  • Freeモナド
  • 存在型による開かれた型
  • それぞれの「機能」が正しく、あつかわれることの、型による保証

Freer Effectsでの改善点

  • FreeモナドからFreerモナド(Operationalモナド)へ
    • fmapによるオーバーヘッドの解消 (効率の向上)
    • 「機能」の本質だけを定義できる (コードがわかりやすくなる)
  • Freerモナドをさらに効率化
    • 関数を合成するのではなく、データ構造のなかにためておく
    • 関数すべてを実行するのではないようなときに有利

みっつの本質と、ひとつの効率化

つまり、Freer Effectsはつぎの、みっつの本質で構成される。

  • Freerモナド: 型引数をとる型を、モナドに変換する
  • Open Union: あとからメンバーを追加できる型
  • 型による安全の保証: 型によって「まちがった操作」からプログラマを守る

さらに、効率化のために、つぎのような技法を使用している。

  • 関数をためておくデータ構造: いちいち関数合成するのではなく、関数をデータ構造に保管しておき、必要に応じて適用していく

目次

(0). 導入

  1. Freeモナドの概要
    • Freeモナドとは
    • FreeモナドでReaderモナド、Writerモナドを構成する
  2. 存在型(ExistentialQuantification拡張)の解説
  3. 型シノニム族(TypeFamilies拡張)の解説
  4. データ族(TypeFamilies拡張)の解説
  5. 一般化代数データ型(GADTs拡張)の解説
  6. ランクN多相(RankNTypes拡張)の解説
  7. FreeモナドとCoyoneda
    • Coyonedaを使ってみる
    • FreeモナドとCoyonedaを組み合わせる
      • いろいろなモナドを構成する
  8. Freerモナド(Operationalモナド)でいろいろなモナドを構成する
    • FreeモナドとCoyonedaをまとめて、Freerモナドとする
    • Readerモナド
    • Writerモナド
    • 状態モナド
    • エラーモナド
  9. モナドを混ぜ合わせる(閉じた型で)
    • Freerモナドで、状態モナドとエラーモナドを混ぜ合わせる
  10. 存在型による拡張可能なデータ構造(Open Union)
  11. 追加の言語拡張
    1. ScopedTypeVariables拡張
    2. TypeOperators拡張
    3. KindSignatures拡張
    4. DataKinds拡張
    5. MultiParamTypeClasses拡張
    6. FlexibleInstances拡張
    7. OVERLAPSプラグマ
    8. ...
  12. モナドを混ぜ合わせる(開いた型で)
    • FreerモナドとOpen Unionを組み合わせる
    • 状態モナドにエラーモナドを追加する
  13. Open Unionを型によって安全にする
  14. Freer Effectsで、IOモナドなどの、既存のモナドを使用する
  15. 関数を保管しておくデータ構造による効率化
  16. いろいろなEffect
    • 関数handleRelayなどを作成する
    • NonDetについて、など

参考

Freer Monads, More Extensible Effects - SlideShare