圏論は数学の一分野です。これを学ぶのには「数学書」を手に取るのが王道なのですが、残念ながらこれは大部分のプログラマに理解できる言葉では書かれていません。「定義
・命題
・証明
」の積み重ねで書かれています1。ここで大半のScalaプログラマは苦い顔をすると思います。もう少し分かりやすいScalaプログラマ向けの圏論入門がないかと探してみると「Haskell
」向けの記事が大量に引っかかるでしょう。ここで多くのScalaプログラマは心を折られてしまいます。「圏論」はまだScalaプログラマには早すぎたんだと・・・ 本記事ではそんなあなたに贈る3つの文献をご紹介したいと思います。
(本記事は自分のブログからの転載記事です。)
はじめに
本記事は圏論に興味があるScalaプログラマを対象にしています。特にプログラマにとって実用的な圏論の知識をScalaを通して身につけたい方にオススメします。
プログラマが圏論を学ぶべき理由
プログラマが圏論を学ぶべき理由に関しては圏論入門レベルの自分があまり大きなことは言えないので、「Category Theory for Programmers Scala Edition」の序文から3つの文章を引用しようと思います。
First, category theory is a treasure trove of extremely useful programming ideas.
Category Theory for Programmers Scala Edition
(意訳) 最初に、圏論はめちゃくちゃ役立つプログラミングのアイデアの宝庫です。
I would go as far as to argue that category theory is the kind of math that is particularly well suited for the minds of programmers.That’s because category theory — rather than dealing with particulars — deals with structure. It deals with the kind of structure that makes programs composable.
Category Theory for Programmers Scala Edition
(意訳) 圏論はプログラマの心理に特に適した数学の分野であるといっても過言ではないと思います。それは圏論が個々の詳細よりもむしろ構造を扱うからです。圏論はプログラムを合成可能にする特定の構造を扱います。
Composition is at the very root of category theory — it’s part of the definition of the category itself. And I will argue strongly that composition is the essence of programming.
Category Theory for Programmers Scala Edition
(意訳) 合成は圏論の重要な根幹を成しており、圏自体の定義の一部でもあります。そして合成はプログラミングの本質であると、はっきり述べておこうと思います。
オンラインで読めるオススメ文献 - 3選
本記事は「Scalaプログラマに適した圏論の文献紹介」という趣旨なので、以下の条件に当てはまる文献を3つに絞って紹介したいと思います。
- 圏論の概念(特にモノイド、関手、モナド)に触れている
- Scalaで解説がしてある
- 定理の証明が極力載っていない
- オンラインで無料で読める
Category Theory for Programmers Scala Edition
まずは前述した「Category Theory for Programmers Scala Edition」を紹介します。
-
Category Theory for Programmers: The Preface | Bartosz Milewski's Programming Cafe
- 元のHaskellで書かれたページ
-
Category Theory for Programmers Scala Edition
- Scalaエディションのダウンロードページ
- 上記のページから「category-theory-for-programmers-scala.pdf」をダウンロード
この本はもともとHaskell(と若干のC++)で書かれていた例に、後でScalaの例を付け加えたものになっています。この本の特徴のひとつは豊富な図解とスニペットです。これは具体的に引用して見てもらった方が早いと思います。以下は10章の自然変換で使われている4つの図になります。
番号と赤い矢印は自分が書き足したものです。一般の数学書による自然変換の説明だと最後の4番目の図のしかも右側の可換図式しか描かれていない場合がほとんどだと思います。しかし本書では1番目の図で同じ圏に移す2つの関手F
とG
が示されて図式が犬と豚に変換されているイメージが描かれています。2番目の図では、自然変換が対象
を移すことを示し、3番目の図で対象だけでなく射
も移すことを示しています。そして3番目を簡略化したものが4番目の図になることが分かります2。
このように本書では圏論の概念が豊富な図によって解説されています。またソースコードもHaskellとScalaのコードが一緒に載っていて非常にわかりやすいです。以下の引用はList
の長さを示すlength
関数が自然変換であることの説明に使われているコードです。
length
関数は一般的にはList[A] => Int
の関数でList
関手をInt
に変換するものですが、Int
を定値関手であるConst[E, A]
に埋め込まれたConst[Int, A]
と見做すことでlength
を関手間の変換、つまり自然変換になることを示しています。本書では関手間のパラメトリックな多相関数は常に自然変換になることを述べています。
上記のように本書では一貫してHaskellのコードが青、Scalaのコードが赤で示されており非常にわかりやすくなっています。一般的な圏論のプログラミングへの応用ではHaskellを例に出されることが多いので、このように併記してある文献はHaskellを学びたいScalaプログラマにとっても嬉しいと思われます。
最後に本書の内容と構成に関してですが、自分は圏論を学びたいプログラマにとっては非常に秀逸だと思いました。少なくとも数学にはあまり自身がないけどプログラミングに圏論を活かしたいプログラマにとっては必要な概念はほぼ本書で触れられていると思います。
以下に本書の目次(一部抜粋)を載せておきます3。また、自分の日本語訳とプログラマとして読んだ方がいい章を5段階評価で★印を付けています。本書を読む参考にしてください。
目次(日本語訳付き)
Writer
圏)Writer
)
Maybe
関手)Optional
)List
関手)Reader
関手)
Writer
関手)
do
記法)
Scala with Cats
次に紹介したいのは「Scala with Cats」です4。CatsはScalaで関数型プログラミングをサポートするためのライブラリで、主に型クラスを提供しています。この型クラスにはモナド(Monad
)や関手(Functor
)も含まれており、圏論をプログラミングに応用する上で重要な役割を果たしています。
この本の特色は「型チャート
」が豊富に載っていることです。Scalaの型は圏論においては対象
や関手
やモナド
だったり様々ですが、それらの変換の様子が図に表されているので非常に分かりやすくなっています。以下の引用は反変関手の型チャートになります。
本書の構成で秀逸なのは、型クラスの説明に留まらず「Case Study(事例)」と「Solution(答え)」が載っていることです。Case Studyには、具体的のどのようなケースで型クラスを使えばいいかが載っています。「Solution」には、各章に豊富に散りばめられた「Excercise」の答えが載っています。従って本書を読むことで圏論の一部を「実務」でも応用できるようになると思います。
以下に本書の目次(一部抜粋)を載せておきます5。また、自分の日本語訳付けていますが・・・途中で力尽きました。本書を読む参考にしてください。
目次(日本語訳付き)
Eq
)Int
の比較)Option
の比較)
contramap
メソッド)imap
)Contravariant
とInvariant
)Contravariant
)Invariant
)
Either
)
Either
への変換)MonadError
)
MonadError
型クラス)MonadError
のインスタンス)Eval
モナド)
Eval
の評価モデル)Eval
)Eval.defer
)Writer
モナド)
Writer
の作成と開封)Writer
の合成と変換))Reader
モナド)
Reader
の作成と開封)Reader
の合成)Reader
でハッキング)Reader
を使うか?)State
モナド)
State
の作成と開封)State
の合成と変換)
Semigroupal
)
Apply
構文)Functor
とApply
構文)Semigroupal
の異なる型への適用)
Semigroupal
のモナドへの適用)Validated
)Validated
のインスタンス作成)Validated
のインスタンス結合)Validated
のメソッド)Apply
とApplicative
)Foldable
とTraverse
)
Foldable
)
猫番
最後に紹介したいのが「猫番」です。紹介する中では唯一の日本語で読める文献です。現在は「O日目」から「17日目」まで公開されており、著者が「Cats」を使って理解していく過程が記録されています。後半はより「圏論」の説明に移っています。
「猫番」は前二つの文献と比べ非常に自由に書かれていて、独特な構成になっています。ただそれが不思議と読みにくいという訳でもなく、著者と一緒に「Cats」や「圏論」を旅をしている気分になれるところがこの文献の面白いところです。もっと気楽に圏論に触れてみたい人や圏論の雰囲気を味わってみたい方はこの文献から読むといいかもしれません。
プログラマが圏論で学んでおいたほうがよい概念
とりあえず「Category Theory for Programmers Scala Edition」に出てきた概念の中で、プログラマが学んでおいた方が良いと思うものを以下に分類してみました6。これはあくまで数学が苦手な圏論入門者である自分の私見です。
-
必ず学んでおきたい
- 圏、関手、自然変換
- 集合の圏(Set)、圏の圏(Cat)、関手圏
- 半群、モノイド
- モナド、クライスリ圏
- 普遍的構成(普遍性)
-
できれば学んでおきたい
- 積、余積
- 同型
- 双対
- 冪、デカルト閉圏
- モノイダル圏
- 自由モノイド、自由モナド
- F代数、T代数
-
余力があれば学んでおきたい
- ホム関手、表現可能関手
- 米田の補題、米田埋め込み
- 極限と余極限
- 随伴
- カリー=ハワード同型
-
興味があれば学んだ方が良い
- エンド
- カン拡張 ←
全ての概念
- 豊穣圏
- トポス
- ローヴェア理論
圏論は非常に多くの概念が出てくるので無理せず少しずつ消化していくのが良いと思われます。自分が圏論に興味を持ち始めたのは「モナド」に出会ってからでした。以下の言葉の意味を知りたくて圏論を始めたのがきっかけです。
モナドは単なる自己関手の圏におけるモノイド対象だよ。何か問題でも?
フィリップ・ワドラー
この言葉の意味は恐らく「必ず学んでおきたい」まで理解できればなんとなく意味が理解できるようになると思われます。さらに圏論にはパワーワード「全ての概念はKan拡張である
」7があって、いつか理解できればいいなと思っています。
まとめ
本記事ではプログラマがなぜ圏論を学ぶべきかを説明し、Scalaプログラマが圏論を学ぶ上で有用な以下の3つの文献を紹介しました。
本記事がScalaで圏論を学んでみたい方の一助になれば幸いです。
もっと圏論を学びたい人向けのオンラインで読めるオススメ資料
残念ながら本記事の趣旨には合いませんでしたが、プログラマが圏論を学ぶ上でぜひオススメしたい資料です。
- プログラマーのための圏論
-
物理学者のための圏論入門
- 物理学者ではなくても圏論の基本的な概念を理解できる非常にオススメの資料です
- 特に
普遍射
の説明が秀逸で、会社組織に擬えての説明がツボりました
-
圏論によるプログラミングと論理
- 灘校パソコン研究部の部誌(2013年)に掲載されていたものです
- 普通に書店に並んでいてもおかしくないボリュームとクオリティです
- 圏論だけでなく数学やコンピュータサイエンスの基礎も補完しています
-
圏論 | 壱大整域
- 圏論の概念を本気で理解したくなったらここに駆け込んでください
- ただしストイックな数学スタイルで書かれているのでプログラマには少し辛いかもしれません
-
ときどき証明をつけずに
「簡単(自明)なので証明は読者に委ねる」
というパワーワードが記載されています。もちろんプログラマにとって「簡単」ではありません・・・ ↩ -
実際には3番と4番の図の間に逆射を持っていた場合の図が挟まっています。 ↩
-
掲載している目次は、「Conclusion」、「Challenges」、「Bibliography」等の見出しは削っております。これは本書の概要を知る手がかりにはならないと考えたからです。正しい目次は直接文献をご確認ください。 ↩
-
この本はもともと「Scalaz」という別のライブラリ向けに書かれていたものが、Cats向けに書き直されたものです。書き直された当初は「Advanced Scala with Cats」という名前で有償でしたが、無償化されるにあたって「Scala with Cats」という名称に変更され可愛らしい猫の表紙が付きました。 ↩
-
掲載している目次は、「Summary」、「Excercise」、「Solution」等の見出しは削っております。これは本書の概要を知る手がかりにはならないと考えたからです。正しい目次は直接文献をご確認ください。 ↩
-
ここで列挙する概念は一般的な圏論に登場する概念から選択しています。プログラミングの文脈で登場する代数的データ型や型クラスは含まれていません。 ↩