用語と記号のオーバーロード〈多義的使用〉はホントに悩みのタネです。混乱と誤解を避けるためにオーバーロードはやめようと思うことは多いのですが、あまり律儀にオーバーロード解決すると用語と記号のインフレーション〈急激な増加〉を引き起こして現実的ではありません。
習慣や癖、あるいは不注意からオーバーロードを使ってしまうことがあります。それでトラブルにならなければいいのですが、混乱と誤解の原因を作ってしまったときは「あー、やっちまった」と後悔します。
内容:
随伴系の反転置写像
随伴関手ペア〈adjoint pair of functors | pair of adjoint functors〉とは、圏の圏(2-圏になる)における随伴系〈adjunction | adjoint system〉です。2つの圏、2つの関手、2つの自然変換、2つの等式からなる代数系です(「随伴系はなぜ難しいか」「ガロア接続(順序随伴系)の簡単な例」参照)。
随伴関手ペア F:C → D, G:D → C, F -| G は次のようなホムセット同型を導きます。
- D(F(A), X) C(A, G(X))
同型をこの形に書いたときの左から右への写像を次のように書きます。
- ΦA,X:D(F(A), X) → C(A, G(X))
ΦA,Xを、随伴関手ペア〈随伴系〉の転置写像〈transposition map〉と呼びます。ΦA,Xの逆写像 (ΦA,X)-1:C(A, G(X)) → D(F(A), X) は反転置写像〈opposite-transposition map〉です。
f:F(A) → X in D と g = ΦA,X(f):A → G(X) in C は(同じことだが、g:A → G(X) in C と f = (ΦA,X)-1(g):F(A) → X in D は)(随伴に関して)互いにメイト〈mate〉である、ということがあります。
メイトである2つの射は、異なる圏に在っても(同じ圏のときもあるけど)転置写像/反転置写像により結び付けられているので、なんとなく(あるいは意図的に、ときに不注意で)同一視されることがあります。
例えば、「丸く収まらなかった基底とフレーム」で出した自由ベクトル空間関手・忘却関手の随伴関手ペア F -| U がある状況で、f∈Vect(F({1, ..., m}), V) と g∈Set({1, ..., m}, U(V)) が互いにメイトなら、fとgを同一視することが多いでしょう。それが、「フレームと線形フレームを同一視する/同一視してしまう」背景です。
もちろん、「同一視されることが多い」からといって、イコールだと思いこむのはダメです。区別しないとマズい状況もあります。ここが難しいところですね。
モナドのクライスリ拡張
前節同様 F:C → D, G:D → C, F -| G は随伴関手ペアだとします。「随伴系はなぜ難しいか」で述べたように、随伴関手ペアの構成素〈constituent | 素材〉で重要なモノは単位と余単位と呼ばれる自然変換です。単位・余単位を η::IdC ⇒ F*G:C → C, ε::G*F ⇒ IdD:D → D とします。
随伴関手ペア(より正確には“圏の圏”内の随伴系) (C, D, F, G, η, ε) から、C上のモナド (M, μ, η) を構成できます。モナドの構成素の定義は:
- M := F*G :C → C
- μ := F*ε*G ::M*M ⇒ M:C → C
- η := η ::IdC ⇒ M:C → C(同じモノ)
(M, μ, η) が関手圏 [C, C] 内のモノイドとなることは、随伴系のニョロニョロ法則からすぐに出ます。
f:A → M(B) に対して、f# := M(f);μB :M(A) → M(B) と定義すると、次の等式が成立します。
- [外単位律] f:A → M(B) に対して、ηA;f# = f
- [内単位律] (ηA)# = idM(A)
- [入れ子律] f:A → M(B), g:B → M(C) に対して、(f;g#)# = f#;g#
(-)# をモナドのクライスリ拡張〈Kleisli extension〉と呼びます。KlExt(-) := (-)# とも書くことにすると、クライスリ拡張KlExtは2つのインデックスを持つオペレーター〈コンビネータ〉です。
- A, B∈|C| に対して、KlExtA,B:C(A, M(B)) → C(M(A), M(B))
モナド (M, μ, η) を、(Mobj, η, (-)#) の形で書いたほうが便利なときもあります。後者の形を拡張スタイルのモナドと呼びますが、詳細は「絵算で見る、拡張スタイルのモナドとモノイド・スタイルのモナド」を見てください。
クライスリ拡張と自由拡張
随伴関手ペア F:C → D, G:D → C, F -| G から反転置写像 Φ-1 が決まります。
- Φ-1A,X:C(A, G(X)) → D(F(A), X)
Φ-1A,X = (ΦA,X)-1 です。
h:A → G(X) に対する Φ-1A,X(h) を短く略記したいとき、僕は h∪ を使うことが多いです。転置・反転置を (-)∩, (-)∪ で書くと、絵算との相性がいいのです。が、気分や成り行きで、他の飾り文字で略記することもあります。
Fが自由生成関手で、Gが忘却関手(普通はUと書かれる)のとき、反転置写像 Φ-1A,X:C(A, G(X)) → D(F(A), X) は、射の域を、自由生成された対象にまで拡張する写像になります。よって、Fが自由生成関手のときの反転置写像を自由拡張〈free extension〉と呼びましょう。自由拡張の典型例は、集合からベクトル空間の台集合への写像に対する線形拡張〈linear extension〉です。
h:A → G(X) に対する自由拡張(反転置写像)を h$ (右肩にドルマーク)と略記することにします。以下は、自由拡張に限らず一般の反転置写像に関して成立することですが:
- h$ = F(h);εX
- k:B → A in C に対して、(k;h)$ = F(k);h$
クライスリ拡張と自由拡張のあいだには次の関係があります。
- f:A → M(B) in C に関して、f# = G(f$)
ここでやっとオーバーロードの話ですが、Fが自由生成関手でGが忘却関手のケースで、忘却関手はしばしば省略されます。すぐ上の等式からGを省略すると:
- f# = f$
つまり、省略後の見た目上はクライスリ拡張と自由拡張は同じになります。それで僕は、クライスリ拡張と自由拡張の演算子記号(右肩の飾り文字)をオーバーロードしてしまったのですが、よろしくなかった。意図的にオーバーロードしたというより、気分/成り行きで「まっ、同じ記号でいいか」と。
教訓としては「なんか似てるから」という程度の安直な理由でオーバーロードするのはつつしむべき。構造的・法則的類似性があるときにかぎってオーバーロードすべきですね。