このページは[url=https://www.geogebra.org/m/ddm5798j]マス旅[/url]の一部です。[br][br][b][size=150][color=#0000ff]「圏」は「集合」と「ベクトル」と「群」をゆる~くアレンジしてできた、[br]何かのつながりを俯瞰するときに使える数学のアイディアです。[br][/color][/size][/b][br]知らないものを学ぶという感覚ではなく、[br]ぼんやり気づいていることの明確化だ、と思って付き合いましょう。[br][br]さて、「圏」は「集合」と「ベクトル」と「群」をゆる~くアレンジしてできたものとかきましたが、[br]ざっくり、「圏」(カテゴリー)というカタマリの共通ルールを確認しましょう。[br][br]そして、1つめキーワードである「ファンクター(関手)」に親しもう。
圏の具体と抽象[br][br][size=150][b]<圏とは何か>[br][/b][/size][br][color=#0000ff][b][size=150]「圏」とは、対象と「射」という矢印を持っていて、1という矢印があり、[br]矢印の結合ができて、結合法則が成り立つ、そういうカタマリです。[br]たったこれだけのルールです。[br][/size][/b][/color][br]対象があるところが「集合」と同じだけど、その中身は特に指定されてない。対象は数どころか、同種のものがあつまってれば何でもOK。[br]矢印があるのが「ベクトル」と同じだけれど、始点と終点はあっても位置はない、長さは自由。[br]1と結合法則については「群」と同じだけれど、逆は特になくてOK。[br][br]ここまで読んで、どう思いますか。[br][br]矢印中心で対象はあいまいです。これでいいのか?[br]と思いますよね。あえて、矢印中心にしたのです。[br]これが「圏」の物重視ではな関係重視の思想です。[u][b]internalよりも[/b][/u][u][b]external重視[/b][/u]です。[br][br]矢印の位置も長さがどうでもよくて、つなげ方が大事です。[br]これが、同型なら同じとみなすという位相的な発想が基本にあります。[br]「射」中心の圏論では、対象を[b][u]同型を除いて(up to isomorphism)[/u][/b]区別するのが自然なのです。[br][br][br][b][size=150]<圏の具体>[/size][/b][br]人間の認知構造として、モデルがないと、わかった気にならないものです。[br]そこで、圏の具体を並べます。[br][br]ヒットするものがあるとうれしいです。[br][br][color=#0000ff][b][size=200]圏の名前={対象、射、結合、1}[br][/size][/b][/color]の順に並べてみますね。[br][br][br]整数の整除圏={整数たち、整除、整除の連続、自身を割る}[br]半順序圏={半順序集合の要素、半順序 、半順序の合成、自身との半順序」[b][br]6の約数圏={[1,2,3,6]、xはyの約数、約数の約数、1}[/b][br]先祖圏={[私、母、祖母]、xはy以上の先祖、先祖の先祖、自身}[br][br]Grps(群圏)={群たち、群準同型、群準同型の合成,恒等写像}[br]Sets(集合圏)={集合たち、写像、写像の合成、恒等写像}[br]Tops(位相空間圏)={位相空間たち、連続写像、写像の合成、恒等写像}[br]空圏={空、空、空、空}[br]1圏={1、1→1、1、1}[br][br]グラフ圏={ノード、矢、矢をつなぐ、自己ノードをさすループ}[br]データ型圏={データ型たち(数値、文字列、リスト)、型変換、変換の連続、無変換}[br]すごろく圏={すごろくの位置(振り出し、とちゅう、ゴール)、進む、進むを続ける、休み}[br][br]まだまだありそうですね。[br][br]半群の圏、環の圏、体の圏、.......[br]集合で対象を1つの集合の要素たちにして、射を部分集合にした「部分集合の圏」もできるでしょう。[br]集合たちでも2つの集合の共通部分を射にすると、「共通部分の圏」もできるでしょう。[br]いろいろできそうですね。[br][br]「圏」のアイディアが「[b]普遍性[/b]」のあるものだということが感じられるでしょう。[br][br]さて、次はいよいよ、[br][br][b][size=150][size=200][color=#0000ff]圏と圏をつなぐ矢印であるファンクター(関手)[br][/color][/size][/size][br][/b]を見てみよう。
[b][size=150]<ファンクターはこわさず持ち上げる>[/size][/b][br][br]functorはfunctionと最初の4文字が同じです。[br]働きは似てますが、厳密には違うからこそ違う名前がついています。[br]見慣れないコトバだと思っている人には朗報です。[br][br][color=#0000ff][b][size=150]「ファンクターはセットメニュー化」[br][/size][/b][/color][br]というブンゲン先生の「はじめての圏論」でのたとえが超わかりやすいです。[br][br]H=ハンバーグ圏[br]={[ハンバーグ、チーズハンバーグ、和風ハンバーグ、…]、[br][和風にする、チーズをのせる、...]、[br]射を組み合わせる、素のまま}[br][br]fmap(H)=ハンバーグライスセット圏[br]={[ハンバーグライスセット、チーズハンバーグライスセット、和風ハンバーグライスセット、…]、[和風にする、チーズをのせる、...]、射を組み合わせる、素のまま}[br][br]ここで、Hの2つの対象a=ハンバーグ、 b=チーズハンバーグと、射cheeze:a→b(チーズをのせる)を[br]とりあげましょう。[br]f(a),f(b)の関係はcheezeなので、fmap(cheeze):f(a)→f(a)ですよね。[br][br]HaskellのFunctorの型クラスの定義は次のようになってます。[br][br][b][size=200][color=#0000ff]class Functor f where[br] fmap f :: (a->b) -> fa -> fb[br][/color][/size][/b][br](Haskellは関数の引数にかっこをつけないの上にかいたことと同じです。)[br][b]射をまるごと始点と終点もいっしょに移します[/b]が、始点、終点はライスセットのfが効いてますが、[br]射のチーズをのせるのはそのまま保存されてますね。[br][br]Functorの型には、[b]Maybe[/b]というインスタンスもあります。[br]Maybeはたぶんコケるかもというデータ型です。[br]こけても安全にデータとして渡されます。[br]「fmap」はmapだけどファンクターのマッピングですよという、[br]一般のmapと区別するためのワードですので深入りしないでいいです。[br]「where」はHaskellの条件句の開始部分で左カッコ程度の意味ですね。[br][br]instance Functor Maybe where[br] fmap f (Just x) = just (f x)[br] fmap f Nothing = Nothing[br][br]似たものに[b]Either[/b]というインスタンスもあります。[br]instance Functor (Either a) where[br] fmap f (Right x) = Right (f x)[br] fmap f (Left x) = Left x[br][br]Haskellは型が厳密な言語なので、ファンクター型が種類わけされています。[br]Pythonとは現状真逆で型にうるさくないなのでFunctorはもっとゆるく使えましたね。[br][br]たとえば、[b]PythonのFunctorのMaybe[/b]の使い方は、[br]from pymonad.maybe import Just, Nothing[br]def extract_addressM(X):[br] return Just(X["A"]) if "A" in X else Nothing[br]というように、[br]辞書型のデータのaddress項目を調べて、欠損してないとJustでくるみ、欠損してるとNothing[br]を返す。JustもNothingも予定された値だから欠損値でもエラーがおきずに動かせます。[br][br]Nothingじゃあさみしいと思ったら、[br]def extract_addressE(X):[br] return Right(X["address"]) if "address" in X and X["address"] is not None else Left("Address がありません")[br]Either型を使って、欠損値のときはLeftにメッセージをくるみ、データがあればRightにくるんで送ります。[br][br]これは、単独処理ではなく、複数の項目があればこのような関数をバケツリレーできます。[br]変なデータがまざっていても、エラーが起きずに情報収集ができます。[br]くわしくは、こちら「[url=https://www.geogebra.org/m/twxxx3yq#material/huczjcdf]FP:モナドで現実データ世界を安全に過ごそう」[/url]をご覧ください。[br][br][b][size=150]<振り返り>[br][/size][/b]今の3つの例からわかることは何でしょう。[br]ブンゲン先生の例は[br]「ハンバーグ圏」の構造を持ち上げて「ライスセット圏」を作りました。[br]Maybeは[br]「データ圏」の構造を変えずに、「Maybe圏」を作りました。[br]Eitherは[br]「データ圏」の構造を変えずに、「Either圏」を作りました。[br][br]これって、圏を圏に移す射です、1対1で構造を壊さず全体を持ち上げてますね。[br]ということは[br]ファンクター={圏たち、ファンクター、合成、恒等射}という圏になっているということですね。[br]このしくみは、[br]2の約数圏={[1,2]、約数、合成、自分自身の約数}という超シンプルな圏と対応がつくね。[br]ファンクターを使うと、圏の同型写像の圏を作れそうですね。[br]だた、準同型ではなく、同型といえるためには逆戻りできないといけない。[br]厳密には、逆射としての逆ファンクターが構成できると、「[b]圏同型[/b]」と言えそうだね。また、ファンクターは射の1つだから、[br]射の合成としてファンクターのバケツリレーができるということも言えるでしょう。[br]たとえば、「ライスセット圏」にビールをつけて「ビールライスセット圏」もできるでしょう。[br][br][br][b][size=150]<さらに俯瞰しよう>[br][/size][/b][br]圏たちが、対象でファンクターが射となる圏が作れるということは、[br]圏と圏をつなぐファンクターを複数用意することができるはずだ。[br]さっきの例では、[br]1つのデータ圏に対して、ファンクターを変えたために、Maybe圏とEiger圏ができた。[br]でも、圏Cに2つのファンクターF,Gをして同じ圏Dができることもありうるでしょう。[br]そうすると、F、Gは違ってみえても、[br]2つの[color=#0000ff]ファンクター[b]FをGに翻訳する対応が自然にできるはず[/b][/color]ですね。[br]これを[b][color=#0000ff][size=200]自然変換(natural transformation)[/size][/color][/b]という。[br][br]圏Cの中の[b]射f:a→b[/b]に目をつけてみよう。[br]射がそれぞれ持ち上げられるとして、[b]F(f): F(a)→F(b)とG(g):G(a)→G(b)[/b]とする。[br]そして、FモノからGモノへの翻訳をφとしたら、[br]F(a)からG(b)への射は[br][b]φaしてG(f)でも、F(f)してからφbしても[/b]同じはずだ。[br]これを「[b]図式が可換[/b]」だという言い方をします。[br]圏論の証明の基本技です。[br][br]群論の証明でもよく出てきましたね。[br]グラフをかくと、四角形ABCDができてて、AからCへの矢印は[br][b]AB+BCでも、AD+DCでも射の合成は同じ[/b]になりますよ[br]というものでしたね。[br][br]イメージとしたら、「ビールライスセット圏」は[br][b]ピールが先でもライスが先でも、[br]結局は、「ビールライスセット圏」ができる[/b]でしょということですね。
圏の視覚化をしてみる。[br][br][size=150][b][u][color=#9900ff]課題:自然変換φの図式が可換であることを視覚化しよう。[br][/color][/u][/b][/size][br]#Pythonを使わなくても、geogebraで図式がカンタンにかけます。[br]#オブジェクトの設定のラベルの変更によって、記述の自由度があがりますね。[br]#タイトル「自然変換φの図式が可換」[br]#四角形ABCDをかきます。[br]A=(-3,3)[br]B=(-3,-1)[br]C=(3,-1)[br]D=(3,3)[br]φa=Vector(A,B)[br]φb=Vector(D,C)[br]Ff=Vector(A,D[br]Gf=Vector(B,C)[br]4点A,B,C,Dの設定を順にひらいて[br]ラベルをF(a),G(a),G(b),F(b)に変更します。[br]ビューの格子と軸を設定で非表示にすると、図に見えますね。[br]
[b][size=150][u][color=#9900ff]課題:データ圏をMaybe圏やEither圏に持ち上げるようすを視覚化しよう。[br][/color][/u][/size][/b][br]Pythonを使わなくても、geogebraでカンタンに作れます。[br]#タイトル「データ圏をファンクターを使って、Maybe圏またはEither圏へ持ち上げる」[br]a=slider(-10,10,1) #アニメーションにする。[br]JorN={"Just " + a, "Nothing"}[br]Maybe=if(a>=0, JorN(1), JorN(2)) #太字で青で文字サイズを大にする。[br]RorL={"Right( " + a + " )","Left(負のデータです)")[br]Either= if(a>=0, RorL(1), RorL(2)) #太字で緑で文字サイズを大にする。[br]b=CheckBox(if(On),Maybe,Either) #Maybeに連動して作る。Eitherの設定で上級でb==falseとする。[br]ビューの格子と軸を設定で非表示にすると、図に見えますね。[br][br]