Skip to content

Instantly share code, notes, and snippets.

@okapies
Last active August 29, 2015 14:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okapies/2e3a878fd8f7a980d3e5 to your computer and use it in GitHub Desktop.
Save okapies/2e3a878fd8f7a980d3e5 to your computer and use it in GitHub Desktop.
FP in Scala chapter notes - Chapter 11: Monads

FP in Scala chapter notes - Chapter 11: Monads

The original is licensed using the MIT license.

Eilenberg-Moore 圏

モナドのもう一つの圏論的な見方は Eilenberg-Moore 圏だ。モナドの EM 圏は、モナドの代数の圏だ。

例えば、List モナドの代数は Scala の Monoid だ。List モナドの EM 圏は、モノイドを対象 (object) としモノイド準同型(10 章を参照)を射 (arrow) とする圏だ。

一般的に、モナドの EM 圏は以下のメソッドに見られる (source: Theory Lunch):

  1. モナド FF-代数 は、型 A と、a(unit(x)) == x かつ a(join(x)) == a(map(x)(a)) であるような関数 a: F[A] => A で与えられる。
  2. F-代数 a: F[A] => A から F-代数 b: F[B] => B への F-代数の射は、b(map(x)(f)) == f(a(x)) であるような関数 f: A => B で与えられる。
  3. モナド F の Eilenberg-Moore 圏は、F-代数を対象 (object) とし F-代数同士の射を射 (arrow) とする。恒等射はまさに identity 関数で、射の合成は普通の関数合成で与えられる。

Monoid[A] がまさに List-代数であることをこの定義から見ることができる:

def fold[A](implicit M: Monoid[A]): List[A] => A =
  _.foldRight(M.zero)(M.op)

これは List-代数で、なぜなら fold(List(x)) == x だからだ(つまり、何かをリストの中に入れて、次にそのリストを畳み込んでも何も起きない)。また、fold(x.flatten) == fold(x.map(fold.apply)) だ(つまり、一連のリスト群を結合してその結合したリストを畳み込むのと、一連のリスト群をそれぞれ畳み込んでその結果のリストを畳み込むのは同じことだ)。

これは、”List はモノイドのモナドである”ということだ。

Option の EM 圏も容易に見つけることができる(Edward Kmett に感謝)。型 Option[A] => A についてのあらゆる Option-代数は、型 A の値 a により与えられ、_.getOrElse(a) で実装される。つまり Option の EM 圏は、普通の Scala の_値_を対象 (object) とし、全ての o: Option[A] について o.map(f).getOrElse(b) == f(o.getOrElse(a)) を満たす 値 a:A から 値 b:B への Scala の関数 f: A => B を射 (arrow) とする。つまり、これらの関数は a を与えられると b を返す。

Reader[R,_] モナドの EM 圏は、対象 (object) のそれぞれが値 r:R によって与えられ、_.run(r) で実装される。射は、結果型 A から他の型 B への Scala の関数だ。

Id(恒等モナド)の EM 圏は、Scala の型の圏そのものだ。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment