冪対象 mapping object, exponentiation

1. 関数を要素とする集合(対象)

対象 A から B への射のひとつが f : A -> B だったとする。しかし、対象 A から B への射はひとつだけではない事が普通だろう。g : A -> B もあるかもしれない。このような対象 A から対象 B への射を全て集めたものを冪対象 BA と言う。

しかし、射の集合のようなものをどうやって射のみであらわせるのだろう。そこで、射そのものを対象で表すのは難しそうなので、先ず射の名前を集めた対象(集合)を考えてみる。このような射の名前を集めた集合をかりに BA と呼ぶ事にしよう。

つぎに、射の名前と値の集合 A の直積集合を考えてみる、これは BA × A で表す事ができる。この集合の要素は、BA の要素である射の「名前」fi と A の要素である aj のペア (fi, aj) である。

このペアは fi という名前の射を aj に関数適用した値 b ij に対応しているはずである。そこで射の名前のペアと射の値を対応させる射 ev を考えることにする。すなわち、

ev : BA × A -> B

だ。ところで圏論では対象 A の要素は終対象 1 から対象 A への射 f : 1 -> A で表す事ができる。そこで、

f : 1 -> BA

という終対象から射の集合への射を考えると f は BA の1個の射の名前を指し示す事になる。

同様に終対象 1 から値の対象 A への射 a を考えると、

a : 1 -> A

射 a は値の対象 A の特定の値を指し示す。これと前回述べた射の積を利用して、

f × a : 1 × 1 -> BA × A

という射を作ると。f × a は対象 BA のひとつの射の名前と対象 A のひとつの値の要素とでつくられたペアである BA × A の要素を指し示す事になる。したがって、これに上に述べた関数の名前と値のペアを評価する関数 ev を適用するとその値である B の要素を指し示す事ができる。つまり、

ev . (f × a) : 1 × 1 -> B

である。射 ev は始対象2つの積を domain とし、値 B の特定の要素を指し示す関数である。これでめでたく、関数を値に関数適用したときの値を、ev . (f × a) のように射のみを使って表現できた。

上の例は1個の関数を1個の値に関数適用した場合だったが、1個の関数を A の全ての要素の値に関数適用する方法も考える事ができる。この場合の射は a ではなく idA (identity) を使って次のようにする。

ev . (f × idA) : 1 × A -> B

この場合射 ev . (f × idA) は全ての対象 A の要素を関数 f によって対象 B の要素に対応付ける。

最後に BA の部分集合について考えてみる。任意の対象 C から BA への射

g : C -> BA

の像 g( C ) は BA の部分集合を定める。したがって次のような射

ev . (g × idA) : C × A -> B

は複数の A -> B の射のそれぞれの対象 A の値についての対象 B の値を定める。これで、次の冪対象の定義を理解する準備ができた。

2. 冪対象の定義

冪対象の定義はつぎのようになる。

定義
C において下記の (1) (2) が成立するとき、C は冪 exponentiation を持つと呼ばれる。
(1) C の任意の対象には、その積が存在する。
(2) C の任意の対象 A, B について、次の条件 [#] をみたす対象 BA と射 ev : BA × A -> B が存在する。
条件 [#] : 任意の対象 C と射 g : C × A -> B について、ev . (^g × idA) = g をみたす ^g が一意的に存在する。ただし、
g : C × A -> B
^g × idA : C × A -> BA × A
ev : BA × A -> B

この定義の条件が束縛しているのは対象 BA と射 ev の性質だ。対象 BA が冪対象であるためには、BA と射 ev が上述の条件を満たしていなければならない。

前述のセクションで述べたように、射 ev . (^g × idA) は複数個の A -> B の射の対象 A の全ての要素に対する値を指し示している。これが上の定義を満たしているとき、どんな

g : C × A -> B

に対しても ^g : C -> BA を見つける事ができる。この場合 C は A -> B の全ての射のうちのいくつかを指定する添数と考える事ができる。すなわち、

fc : A -> B, c ∈ C

である。

これで圏に関数を要素とする対象を導入する事ができた。いままでの経過を振り返ってみると、圏の性質が、だんだん Haskell のプログラムに似てくる。射を表す形式は関数の type signature そのままなので親しみがわく。Haskell のプログラムは圏のひとつなのだからそれは当然なのだが、Haskell のプログラムの構造が射のネットワークで抽象化できるのが分かる。圏論にもっと詳しくなれば、Haskell のプログラムのデザインパターンのようなものを射の図式で表現できるようになるのかもしれない。

特に射で表現する圏論の表現力の簡潔さは素晴らしい。上で述べたように複数の関数の全ての値のようなものも

ev . (^g × idA)

のようにさらりと表現してしまえる。これを集合の言葉や手続き型のプログラムで表現したらどれだけ長い記述になってしまうだろうと思ってしまう。

そのうち、圏論の学習が IO モナドを理解するためだけにあるのではない事が分かってくる気がする。

『圏論による論理学 高階論理とトポス』清水義夫著を参考書にして、圏論で何を表現したいのかということについて思いついた事を書き散らしてきたが、そろそろ理解の限界に近づいているようだ。圏論について語るためにはもっともっと理解しないと行けないことが多い。それにはたくさんの時間がかかりそうなのでこの記事のシリーズもそろそろ終わりにしたい。

次回の記事でサブオブジェクト・クラシファイアーについて挑戦するが、そこまで分かるとトポスの定義にたどり着くのでそこでこの圏論シリーズを終わりにするつもりだ。

ただ、圏論の勉強が単に IO モナドの理解のためだけではなく、Haskell のプログラミングの本質にも関わってきそうな事が分かって少しやる気が出てきた。そのうち出てくるだろうけれど Haskell のプログラマーの立場からの圏論の参考書が待ち遠しい。
[PR]
by tnomura9 | 2014-04-17 08:15 | 圏論 | Comments(0)
<< 声帯を横に広げる発声法 射の積 product of ... >>