JavaScriptカテゎリヌ理論。 パヌト1.セットのカテゎリ



抜象化は、ITの䞻芁な手法の1぀です。 プログラミング蚀語やモデリング蚀語、プログラミングパラダむム手続き型、関数型、OOPなどは、どのように、䜕から抜象化するかずいう質問に察する答えを提䟛したす。 さらに、各アプロヌチの支持者は、ある皮の抜象化を提䟛したす。

真の普遍的な抜象化をご芧になりたい堎合は、...に参加しおください 。カテゎリの理論を研究しおください 。 写真ずJavaScriptコヌドを含むセットのカテゎリの䟋では、カテゎリ理論の最も基本的な抂念である制限、ナニバヌサルプロパティに぀いお説明しおいたす。 カテゎリ理論の蚈算面が考慮されたす。

たた、JavaScriptのクラス、䞍玔物、およびブレンドに぀いおも少し説明したす。

蚘事の䟋はこちらにありたす 。

はじめに


誰もがカテゎリヌ理論に぀いお聞いたこずがあるず思いたす。 これはクヌルな銀の匟䞞の理論であり、非垞に異なるものを䞀様に蚘述するこずができるず聞きたした。 関数型プログラミング蚀語で積極的に䜿甚されおいるず聞きたした。 䞻にカテゎリヌ理論に基づいたプログラミング蚀語やコンピュヌタヌ代数システムに぀いお聞いたこずがある人もいるかもしれたせん。

このトピックに関する倚くの曞籍や蚘事がむンタヌネット䞊にありたす。 しかし、通垞は、数孊者や科孊や、Haskell、MLのような奇劙なこずに埓事するIT専門家に焊点を圓おおいたす皮肉-カルマにマむナスを入れる必芁はありたせん。通垞、Saint Haskellに蚀及した埌は無駄です。

たた、JavaScriptを䜿甚しお䞀切れのパンを毎日手に入れる単玔な勀勉な劎働者にずっお、カテゎリヌ理論の利点はほずんど理解されおいたせん。 この䞀連の蚘事を読んだ埌、明確になるずは玄束したせん。 しかし、すべおがうたくいけば、倚分䟿利なこずをするアプリケヌションを実行するでしょう。

私はすぐに、数孊教育ではなく工孊を持っおいるず譊告したす。 したがっお、蚘事で厳密な定矩、定理の蚌明などが芋られるず予想する堎合、それは衚瀺されたせん。 それどころか、すべおは「指で」説明されたす。 䞍正確な点があれば、曞いおください、私はいく぀かの点で間違っおいるかもしれたせん。

カテゎリずは䜕ですか


カテゎリは、次のものに察しお定矩するものです。

蚘号∘は時々省略されたすh gf = hg f

たた、合成の代わりに、射の連結が時々䜿甚されるので、匏ではそれらは図ず同じ順序になりたすf; g; h = f; g; hしかし、そのような蚘録は芋た目ほど䟿利ではないため、たれです。 次の蚘事の芁玠を怜蚎するず、これが衚瀺されたす。

䜕かのカテゎリを構築するには、それが必芁です


圢態玠には、1぀の゜ヌスず1぀のタヌゲットオブゞェクトが必芁です。 3぀以䞊のオブゞェクトを接続するこずも、「宙に浮かぶ」こずもできたせん。  高次のカテゎリは考慮したせん。

合成操䜜は、互換性のある射にのみ適甚できたす。 射f→A→B、gB→C、hC→Dがありたす。構成g∘fたたはf; gは蚱容されたす。 たた、次の構成は蚱可されおいたせんh∘f、f∘f、f∘g。

次に、カテゎリの䟋を考えおみたしょう。 基本的なトポを想像しおください、それはカテゎリヌです。 提瀺された堎合、この蚘事で新しいものを芋぀けるこずはほずんどありたせん。 より基本的なものを読む方が良い。

グラフによっお生成された無料のカテゎリの䟋


匕き続き読み続ける堎合は、より理解しやすいカテゎリを䜜成しようずしたす。 VKontakteペヌゞず、友達、賌読者、賌読しおいる人のペヌゞを提瀺したす。これらはすべお、盎接接続しおいたす。 これはオブゞェクトのクラスになりたす 


フォロヌしおいる党員に察しお、ペヌゞからその人のペヌゞに矢印を描きたす。 あなたをフォロヌしおいるすべおの人に察しお、自分のペヌゞからあなたのペヌゞに矢印を描きたす。 そしお、すべおの友達のために、䞡方向に矢印を描きたす


次に、残りのペヌゞに぀いおも同じこずを行いたす。


ある人が別の人をサブスクラむブする堎合、最初の人は2番目の人を知っおいるず想定したす。 2人が互いにサブスクラむブしおいる堎合友人は、お互いを知っおいたす。 ぀たり このカテゎリの射は、「知っおいる」ずいう関係です。

誰もが自分自身を知っおいお、 同䞀の射を描くず仮定したす


射の合成の操䜜を次のように定矩したす。

fをAがBを知っおいるこずを瀺す射であり、gがBがCを知っおいるこずを瀺す射であるずする。g∘fはAが間接的にCを知っおいるこずを意味する射

したがっお、このカテゎリの射のクラスには、「知っおいる」ずいう関係だけでなく、「間接的に知っおいる」ずいう関係も含たれたす。

䜜曲の動䜜の関連性は明らかです。 AがBを知っおおり、Cを知っおいお、Dを知っおいる堎合、ここで射をグルヌプ化しない方法は、ずにかくAは間接的にDを知っおいたす。

同䞀の射が合成の䞭立的な芁玠であるこずも明らかです。 AがBを知っおいる堎合、自分自身を知っおいおも䜕も倉わりたせん。

グラフによっお生成される無料のカテゎリを䜜成したした 。 䞀方では、この䟋は、どのようにカテゎリからも構築する方法を瀺しおいたす。 䞀方、特定のルヌルに埓っおカテゎリが構築されるこずを瀺しおいたす。

先行予玄の䟋


前の䟋では、オブゞェクトず射は比范的単玔であり、内郚構造が欠けおいるず考えおいたす。

ここで、すべおのペヌゞあなたずあなたが接続しおいる人々が1぀のオブゞェクトであるず想像しおください。 他の人に関連する倚くのペヌゞは異なるオブゞェクトなどです。


このカテゎリにはどのような射がありたすか

たずえば、リレヌション「サブセット」。 すべおの友人、加入者など 個人Aも別の加入者などです。 人B、次にAからBぞの射を描きたす。この堎合、カテゎリであるpreorderを取埗したす。


たたは、たずえば、射ずしお、ペヌゞを匕数ずしお受け取り、それらのペヌゞを返す関数を䜿甚できたす。 この堎合、セットのカテゎリを取埗したす。 セットのカテゎリには、VKontakteペヌゞのセットだけでなく、すべおのセットが含たれおいるため、より正確には、そのサブカテゎリです。

可換図


怜蚎した䟋では、カテゎリを持぀図を特定したした。 しかし、䞀般的に、これらは2぀の異なるものです。 厳密に蚀えば、 ダむアグラムはファンクタヌです。 これたでのずころ、ファンクタヌずは䜕でも構いたせん。

以前の蚘事の 1぀で、モデルずその衚蚘法図、テキスト衚蚘、たたはその他が2぀の異なるものであるこずを既に説明したした。 同様にカテゎリ。

ここでは、ダむアグラムは、オブゞェクトがノヌドずしお衚され、射がノヌド間の矢印ずしお衚されるカテゎリフラグメントの䞀皮の芖芚的衚珟であるず仮定したす。 ただし、ダむアグラムでは、そのフラグメントだけでなく、カテゎリ党䜓を衚すこずもできたす。 1぀以䞊のオブゞェクトず射のみを含むカテゎリがありたす。

チャヌトは、可換たたは非可換の堎合がありたす。

可換図ずは、任意のオブゞェクトのペアに぀いお、射の合成の結果がこれらのオブゞェクト間の方向パスの遞択に䟝存しない図です。

個人的には、ダむアグラムがどのように非可換になるかをすぐには理解したせんでした。 䞊蚘のグラフず事前予玄によっお生成された無料のカテゎリの䟋を芋おください。 2぀のオブゞェクト間に耇数のパスがある堎合、これらすべおのパスは明らかに同等です。1぀のオブゞェクトで始たり、1぀のオブゞェクトで終わりたす。 これらのパスはどのように等しくないのでしょうか

実際、予玄泚文では、最倧で1぀の射がオブゞェクトAからオブゞェクトBに移動できたす。 無料のカテゎリでは、䞀察のオブゞェクト間に耇数の射が存圚する可胜性がありたすコメントの説明を参照が、この䟋ではこれらの射が同等であるこずは盎芳的に明らかですこれらは垞にAが盎接的たたは間接的にBを知っおいるずいう事実を反映しおいたす。しかし、たずえば、オブゞェクトの同じペア間のセットのカテゎリには、いく぀かの完党に異なる射がありたす。 䟋ずしお、2぀のオブゞェクトず2぀の平行射を持぀非垞に単玔な図を考えおみたしょう。 可換ですか


等匏f = gが成り立぀堎合にのみ、可換です。 䞀般に、カテゎリヌ理論では、可換図は方皋匏系を曞く代わりにしばしば䜿甚されたす。 「次の等匏が成り立぀」ず曞いお、リストするこずができたす。 たたは、「次の図は可換である」ず蚘述し、連立方皋匏に察応する図を描くこずができたす。

この図の可換性は、描画されたオブゞェクトず射の背埌にあるセットず関数に䟝存したす。 オブゞェクトAを数倀のセット、オブゞェクトBを幟䜕孊的図圢のセット、射圱fはある数倀に察しおこの数倀に等しい半埄の円を返す関数、射圱gは特定の数倀に等しい蟺の長さの正方圢を返す関数ずしたすこの番号に。 明らかに、これらの2぀の関数は等しくありたせん。぀たり、ダむアグラムは可換ではありたせん。


1぀のカテゎリに数字のセットず数字のセットが混圚しおいるこずを混同しないでください。 同じカテゎリには、倚くのVKontakteペヌゞ、倚くのセット、グラフ、シヌルなどがありたす。これらはすべお、セットの1぀のカテゎリです。 より詳现に怜蚎したすが、最初に゜ヌスコヌドに関する少し䞀般的な情報を怜蚎したす。

゜ヌスコヌドの䞀般情報


゜ヌスコヌドはここにあり、蚘事の䟋はこちらにありたす 。

私は、ES6がただ蚭眮されおおらず、暙準ラむブラリに通垞のコレクションがなかった3幎前にほずんどのコヌドを曞いたこずをすぐに譊告したす。 その埌、セットを実装する必芁がありたした。 そしお、䞀般的に、コヌドはおそらく最適に線成されおいたせん。 正盎なずころ、私はすべおをモゞュヌルに分解しお蚘事を読み、カテゎリ理論がこのすべおの錫よりもはるかに簡単に芋えるこずに気付きたした。

Helpers.jsファむルでは、他のヘルパヌ関数ずずもに、拡匵および結合関数が定矩されおいたす。 extend関数は長い間発明されおきたした。これにより、あるクラスを別のクラスから継承するこずができたす。詳现に぀いおは、 ここで説明したす 。 唯䞀のこずは、私の実装ではクラスに䞍玔物を远加できるこずです。 䞍玔物に぀いおのこの蚘事を読むこずを匷くお勧めしたす。 䞍玔物はサブクラスの工堎ず芋なされ、ES6でコンパクトに蚘述する方法に぀いお説明しおいたす。 䞀般的に、スヌパヌクラスが事前に知られおいない、より䞀般的な継承のケヌスずしおの䞍玔物のビュヌは非垞に興味深いです。

個人的には、Babelなどに煩わされたくないので、゜ヌスコヌドはES5で曞かれおおり、これら2぀の機胜が必芁でした。 䞍玔物は、extendを持぀クラスずしお継承するこずはできたせん。combinedメ゜ッドを䜿甚しおのみ混合できたす。

Category.jsファむルは、特定のカテゎリを継承する抜象クラス「category」を定矩したす。 たた、䞍玔物「完党カテゎリ」ず「共重合カテゎリ」およびそれらの混合物「双極子カテゎリ」も定矩したす。 以䞋で怜蚎するセットのカテゎリは、再び双極子カテゎリであり、任意の双極子カテゎリ「ミックス」で䜿甚できる汎甚アルゎリズムです。 JavaScriptは倚重継承をサポヌトしないため、これらは特に䞍玔物ずしお実装されたす。 さらに、これらすべおに぀いお詳しく説明したす。

Set.jsファむルは、1セットのカテゎリ、2セット自䜓、3関数、および4セットのカテゎリの制限を定矩したす。 理論的には、SetクラスはES6のSetに眮き換えるこずができたす。 関数は、いわゆるグラフの圢匏で実装されたす 。 それらは明瀺的に保存したす


ドメむンずコヌディングドメむンは明瀺的に保存されるため、2぀の関数の構成が有効かどうかを確認できたす。 1番目の関数のドメむンが2番目の関数のコヌドネヌムず䞀臎する堎合にのみ有効です。 たた、ドメむンは、関数が本圓に完党であるか、 郚分的に定矩された関数であるかを確認するために䜿甚されたす 。 コヌドを芋るず、同様のチェックアサヌト呌び出しがたくさんありたす。

関数をグラフではなく関数の圢匏で正確に栌玍するこずはおそらく可胜ですが、これはただ䞍可欠ではありたせん。

SetCategoryView.jsファむルで、d3に基づくセットのカテゎリのグラフ描画。 蚘事のほずんどすべおの図は、その助けを借りお描かれおいたす。 ずころで、d3の4番目のバヌゞョンでは、Force Layoutが改善され、そこで任意の力を個別に決定できるようになりたした。 間違っおいない堎合は、svgのみで機胜する前にドラッグアンドドロップを改善したした。珟圚、canvasで簡単にサポヌトされおいたす。 この図では、理論的に興味深いものを芋぀けるこずができたすが、完党なリファクタリングが必芁です。

Set.htmlファむルには、この蚘事のすべおの䟋が含たれおいたす。

カテゎリの実装を蚭定する


次に、セットのカテゎリからのさたざたな構成ず、それらがコヌドでどのように実装されるかを説明したす。 それ自䜓は、次のファクトリずしお実装されたす。

function SetCategory() { } extend(SetCategory, Category, BicompleteCategory); SetCategory.prototype.object = function (elements) { return new Set(elements); }; SetCategory.prototype.morphism = function (A, B, mapping) { return new TotalFunction(A, B, mapping); }; SetCategory.prototype.id = function (A) { return this.morphism(A, A).initId(); }; SetCategory.prototype.compose = function (g, f) { return g.compose(f); }; 

セットのカテゎリは抜象カテゎリから継承され、双極子カテゎリの動䜜はそれず混合されたす。

このファクトリでは、䜜成するこずができたす


正盎なずころ、カテゎリを工堎にすべき理由をすぐには理解しおいたせんでした。 蚀う、セット、リスト、スタック、ツリヌ、グラフ、およびその他の構造は通垞、それらのすべおの芁玠を明瀺的に保存したす。 カテゎリは同様の数孊的構造に䌌おいたすが、なぜ実装が異なるのですか カテゎリをそのオブゞェクトずモヌフィズムのリポゞトリずしお実装するこずが䞍可胜なのはなぜですか 䞀般的な堎合、カテゎリには無限の数のオブゞェクトず射が含たれおいるためです。 さらに、それらのうち、必芁なものはわずかです。 そしお、それらは、それらに基づいお新しいオブゞェクトずモヌフィズムを構築するために保存する必芁はありたせん。

いく぀かのオブゞェクトず射を䜜成したしょう

 var setCat = new SetCategory(); var obj123 = setCat.object([1,2,3]); var objAB = setCat.object(['a','b']); var objABCD = setCat.object(['a','b','c','d']); var f = setCat.morphism(obj123, objABCD, {1: 'c', 2: 'c', 3: 'd'}); var g = setCat.morphism(objABCD, objAB, {'a': 'a', 'b': 'b'}); var h = setCat.morphism(objAB, obj123, {'a': 1, 'b': 1}); showSetCategoryView('diagram1', setCat, {'A': obj123, 'B': objABCD, 'C': objAB}, {'f': {dom: 'A', codom: 'B', morphism: f}, 'g': {dom: 'B', codom: 'C', morphism: g}, 'h': {dom: 'C', codom: 'A', morphism: h}}); 


実行可胜なJavaScriptコヌドを蚘事に挿入できないのは残念です。 したがっお、写真を挿入する必芁がありたすが、 ここですべおを移動できるこずを繰り返したす 。

゚ピモルフィズム、単型、同型


さお、オブゞェクト、モヌフィズムを䜜成し、それらを矎しく描くこずができたす。 次は

オブゞェクトず射はさたざたなプロパティを持぀こずができ、カテゎリ理論の重芁な郚分はこれらのプロパティの説明ず研究に専念しおいたす。 カテゎリ理論の実装では、これらのプロパティを怜蚌でき、特定のプロパティを持぀オブゞェクトずモヌフィズムを構築できる必芁がありたす。 最も単玔なプロパティから始めたしょう。

セットのカテゎリ内の射は関数であるずいうこずを思い出させおください。 孊校から、あなたはおそらく、機胜が射圱、泚射、党単射であるこずを芚えおいたす。 厳密な定矩はなく、すべおを指で説明するこずを玄束したした。

Surjectionは、倀の範囲からすべおの倀を取埗する関数です。 敎数のセットで定矩された2乗関数は、2、3、5、...の倀をずらないため、射圱ではありたせん。


むンゞェクションは、元のセットのさたざたな芁玠を結果セットのさたざたな芁玠にマッピングする関数です。 さらに、関数の倀の範囲には、定矩領域にプロトタむプを持たない远加の芁玠が含たれる堎合がありたす。


党単射は1察1のマッピングです。 関数は、党射ず射出の䞡方である堎合にのみ、党単射です。


他の数孊的オブゞェクトグラフなどには、射圱、射圱、党射の類䌌物がいく぀かありたす。 したがっお、カテゎリの理論では、この理論はすべおに関するものであるため、これらの抂念を䞀般化するこずを決定し、それぞれ゚ピモヌフィズム、モノモヌフィズム、およびアむ゜モヌフィズムを導入したした。

この䞀般化ずは䜕ですか カテゎリヌ理論では、オブゞェクトず射の内郚構造から完党に抜象化されおいるずいう事実。 䞊蚘の図で行われおいるように、これらのタむプの射を円ず矢印で定矩する代わりに、他の射ずの関係で定矩されたす。

゚ピモルフィズムは、e→A→Bであり、等匏f∘e = g∘eはf = gを意味したす蚀い換えるず、右偎のeに短瞮できたす。


危機にwhatしおいるものを明確にするために、NOT゚ピモヌフィズムの䟋を瀺したす。


䞊の図は可換ですf∘h = g∘h。 これを確実にするために、セットAの各芁玠から矢印をたどるこずができ、遞択されたパスに関係なく、垞にセットCの同じ芁玠に到達したす。 同じ匕数に察する関数f∘hおよびg∘hは、同じ結果を返したす。 しかし関数fずgの等䟡性はこれからは続きたせん。 芁玠「1」の堎合、異なる倀「a」ず「b」を返したす。 しかし、関数hが゚ピモルフィズムである堎合、fずgの等匏は図の可換性から埗られたす。

さらに、「円を通る矢印による遷移」などの詳现は説明したせんが、セットのカテゎリで可換図に぀いお話しおいるずきは、この可換性を垞にこの方法でチェックできるこずに泚意しおください。

繰り返したすが、単射関数は他の関数ずの関係を通しおのみ蚘述され、それらの内郚構造の詳现から完党に抜象化されおいるこずに泚意しおください。 これがカテゎリヌ理論の本質です。

単盞性は、m = A→Bのようなm∘f = m∘gであるため、f = gに埓う぀たり、巊偎のmで省略できる射型です。


同型ずは、逆が存圚する型fA→Bです。 射gB→Aが存圚し、f∘g = id Bおよびg∘f = id Aである


ここで、ちょっずした驚きがありたす。 すべおのカテゎリではありたせんが、射が゚ピモルフィズムであり、単盞であるずいう事実は、同型であるこずを意味したす。 これは、セットのカテゎリは確かにいく぀かの抂念を芖芚化するのに適しおいたすが、誀った類掚に぀ながる可胜性があるこずを瀺しおいたす。

終了、開始、およびヌルオブゞェクト


最埌のオブゞェクトはオブゞェクトTであり、任意のオブゞェクトXに察しお䞀意の射uX→Tが存圚したす。

セットのカテゎリでは、最終オブゞェクトはシングルトンであり、䞀意のモルフィズムは、元のセットの芁玠をシングルトンの単䞀芁玠にマッピングする関数です。 セットのカテゎリには無限の数の終端オブゞェクトがありたすが、それらはすべお互いに同型です。 これは、カテゎリ理論の芳点からは、どのシングルトンが問題であるかは重芁ではなく、同型に至るたでの1぀に圓おはたるすべおが他のシングルトンにも圓おはたるこずを意味したす。


初期オブゞェクトはオブゞェクトIであり、任意のオブゞェクトXに察しお䞀意の射uI→Xがありたす。

セットのカテゎリでは、初期オブゞェクトは空のセットであり、空のセットで定矩された䞀意のモルフザむムは空の関数です。 さらに、セットのカテゎリにはそれぞれ単䞀の空のセットがあり、単䞀の初期オブゞェクトがありたす。


nullオブゞェクトは、開始オブゞェクトず終了オブゞェクトの䞡方であるオブゞェクトです。

セットのカテゎリにれロオブゞェクトはありたせん。 セットを同時に空にしおシングルトンにするこずはできたせん。

いく぀かの重芁な点に泚意しおください。

初期オブゞェクトず最終オブゞェクトは二重の抂念であり、それらは射の方向の反転たで同等です。 最初のオブゞェクトは、デュアルカテゎリの最埌のオブゞェクトになりたす同じオブゞェクトず合成操䜜を持぀カテゎリですが、射は反察方向に向けられたす。 双察性たたは双察性の抂念は、カテゎリヌ理論においお非垞に重芁です。 以䞋に、デュアルコンセプトの䟋をいく぀か瀺したす。

ちなみに、有限オブゞェクトはconach、初期オブゞェクト-konechnyず呌ばれたすが、ここでは、1぀の根本的に新しいプログラミング蚀語の分野にすでに分類されおいたす。 抂念に接頭蟞「co-」を远加たたは削陀するず、二重の抂念が埗られたす。 カテゎリ理論の専門家は、初期のオブゞェクトに぀いお話しおいるこずを理解する必芁がありたすが、私はkokonechnyeオブゞェクトに䌚いたせんでした。

䞊蚘の定矩は、最終オブゞェクトから導かれた射に぀いおは䜕も蚀っおいたせん。 そしおそれらは存圚したす。 たずえば、モルフィズムf{1}→{1,2,3,4}ずグラフ{1,1}、たたはモルフィズムgず同じシグネチャでグラフ{1,2}。 ぀たり それらは存圚するだけでなく、ナニヌクでもないため、将来を芋据えおかなり重芁な圹割を果たしたす。 したがっお、射がそれらにのみ向けられおいるオブゞェクトずしおの有限オブゞェクトの抂念は真実ではありたせん。


最初のオブゞェクトに向けられた射に぀いおは、䜕も蚀えたせん。 セットのカテゎリでは、それらは存圚しないか、空の䞀意の関数であるず想定しおいたす。 原則ずしお、なぜ1぀ではありたせん。 しかし、その埌、各セットは空のセットず同型になりたす。 誰かがこの点を明確にできれば、それは玠晎らしいこずです。

ナニバヌサルプロパティず最も重芁なポむント


䞊蚘の定矩の「...射は1぀だけです...」ずいうフレヌズに泚意しおください。 これは䞀般的にカテゎリヌ理論の研究で芋られたす。 これは「 ナニバヌサルプロパティ 」ず呌ばれたす 。

ナニバヌサルプロパティを䜿甚するず、詳现から抜象化しお抂念を定矩できたす。 開始オブゞェクトず終了オブゞェクトは、空のセット、シングルトン、はい、および䞀般的にはすべおの構造に蚀及せずに定矩されおいるこずがわかりたす。 さお、これは本圓の抜象化です 開発者向けのカテゎリヌ理論のガむドでは、 デカルトの閉じたカテゎリヌやモナドではなく、䞻にそのようなこずに぀いお話す必芁があるず思いたす。

蚀い換えれば、カテゎリヌ理論では、オブゞェクトを内郚実装の説明ではなく、倖郚動䜜の説明、他のオブゞェクトずどのように「盞互䜜甚する」こずができるか、に焊点を圓おおオブゞェクトを定矩したす。 確かに、プログラミング蚀語で通垞行われおいるこずずは少し異なりたすが、このカテゎリの理論は興味深いものです。

詳现からの抜象化により、ナニバヌサルプロパティは同型たでのオブゞェクトを定矩したす。 セットのカテゎリでは、すべおの有限オブゞェクトシングルトンが同型であるこずを既に述べたした。 しかし、これは、ナニバヌサルプロパティを介しお定矩されたオブゞェクトには圓おはたりたす。 原則ずしお、これは非垞に論理的です。2぀のオブゞェクトが倖郚で同じように「振る舞う」堎合それらは同じ普遍的な特性を持っおいたす、それらは同型です。

そしお、おそらく、この䞀連の蚘事党䜓の最も重芁なポむントです。 通垞、ナニバヌサルプロパティには最適化タスクがありたす。これは、ある意味で最適なオブゞェクトたたは射を芋぀けるこずです。 むコラむザヌのセクションでこれに戻りたす。

最終オブゞェクトず初期オブゞェクトの実装


理論が倚すぎるので、有限オブゞェクトず初期オブゞェクトがどのようにコヌドに実装されおいるかを芋おみたしょう。
 SetCategory.prototype.terminal = function () { return new SetTerminalObject(this).calculate(); }; function SetTerminalObject(cat) { this.cat = function () { return cat; }; } SetTerminalObject.prototype.calculate = function () { this.obj = new Set([1]); return this; } SetTerminalObject.prototype.univ = function (A) { var mapping = {}; A.forEach(function (el) { mapping[el] = 1; }); return this.cat().morphism(A, this.obj, mapping); } SetCategory.prototype.initial = function () { return new SetInitialObject(this).calculate(); }; function SetInitialObject(cat) { this.cat = function () { return cat; }; } SetInitialObject.prototype.calculate = function () { this.obj = new Set(); return this; } SetInitialObject.prototype.univ = function (A) { return this.cat().morphism(this.obj, A, {}); } 

あなたは質問をしたかもしれたせんなぜシングルトンずEMPTYセットを実装するのにそんなに倚くのコヌドがあるのですか

最終オブゞェクトず初期オブゞェクトは、単なるセットではありたせん。 普遍的な特性は、それらのためにただ満たされなければなりたせん。それは、いくらかの理論的特性を持ちたせんが、蚈算で積極的に䜿甚されたす。 たずえば、コヌドカヌトの正方圢の補数を蚈算する堎合、オブゞェクトの合蚈の普遍射が蚈算されたす。 これに぀いおは埌で説明したす。

実装では、ナニバヌサルプロパティを持぀構造䜓にメ゜ッドがありたす。


仕事


指の厳密でない定矩を継続し、少し耇雑なオブゞェクトを怜蚎したす。

オブゞェクトX jの積はオブゞェクトXず射圱πj正準射圱ず呌ばれるX→X jであり、任意のオブゞェクトYず射圱f j Y→X jに察しお䞀意の射圱uY→Xが存圚し、πj ∘u = f j 。

カテゎリ理論では、πj∘u = f jの圢匏の等匏を曞く代わりに、同様の図を描き、それが可換であるず蚀うこずができたす2぀のオブゞェクトの䟋ですが、䞀般的な堎合はもっずありたす


セットのカテゎリでは、オブゞェクトの積はセットのデカルト積です。


図では、補品はAxBずしお瀺され、その芁玠は元のセットの芁玠のペアずしお瀺されおいたす。 しかし、これは明確にするために行われ、絶察に必芁ではありたせん 䜜品は䜕でも呌ぶこずができたすが、その芁玠は


積は、倀のペアのセットずしおではなく、射の関係を通じお定矩されたす。 集合のデカルト積ずカテゎリヌ理論のオブゞェクトの積の定矩を比范したす—共通点はありたせん。 カテゎリ理論の詳现から抜象化する䟋が再び衚瀺されたす。

コヌドでは、䜜業は次のように実装されたす。
 SetCategory.prototype.product = function (A, B) { return new SetProduct(this).calculate(A, B); }; function SetProduct(cat) { this.cat = function () { return cat; }; } SetProduct.prototype.calculate = function (A, B) { var obj = new Set(); var mapping1 = {}; var mapping2 = {}; A.forEach(function (x) { B.forEach(function (y) { var z = [x, y].toString(); obj.add(z); mapping1[z] = x; mapping2[z] = y; }); }); this.obj = obj; this.f = this.cat().morphism(this.obj, A, mapping1); this.g = this.cat().morphism(this.obj, B, mapping2); return this; }; SetProduct.prototype.univ = function(m, n) { assertEqualDom(m, n); assertEqualCodom(this.f, m); assertEqualCodom(this.g, n); var obj = m.dom(); var mapping = {}; obj.forEach(function (x) { var s1 = this.f.preimage(m.image(x)); var s2 = this.g.preimage(n.image(x)); mapping[x] = s1.intersection(s2).representative(); }.bind(this)); var u = this.cat().morphism(obj, this.obj, mapping); assertCommutes(this.f.compose(u), m); assertCommutes(this.g.compose(u), n); return u; }; 

蚈算関数は、集合のデカルト積だけでなく、2぀の射元のオブゞェクト䞊の積の正準投圱も蚈算するこずに泚意しおください。 ほずんどの蚈算では、䞻な圹割を果たすのは圌らであり、倧たかに蚀えば、圌らは倚くの人よりもはるかに重芁です。

univ関数は、䞀郚のオブゞェクトず䞀察の射に぀いお、普遍射䞊図のu-を蚈算したす。 䜜品の普遍的な圢態がどのように圹立぀かを芋おみたしょう。

次の図では、オブゞェクトAずB、それらの積AxB、およびモルフィズムf 1ずf 2を持぀任意のオブゞェクトCが衚瀺されおいたす。


セットCの芁玠「1」がセットAの芁玠「1」ずセットBの芁玠「a」にマッピングされおいるこずがわかりたす。セットAxBの芁玠「1」ず同様です。 普遍射の蚈算では、この事実を確立し、集合Cの芁玠「1」を集合AxBの芁玠「1、a」にマッピングするように、普遍射を構築したす。

集合Cの芁玠「4」ず「5」は、射f 1ずf 2によっお同じ芁玠にマッピングされたす。 したがっお、普遍射は、それらを集合AxBの「2、b」の1぀の芁玠にマッピングしたす。

明確にするために、Cがたくさんの猿だず想像しおください。 f 1各猿は、矎しいたたはbeautifulいカテゎリのいずれかに属し、f 2-スマヌトたたは愚かなカテゎリのいずれかに属したす。 次に、普遍的な射圱uは、各猿を4぀のカテゎリのいずれかに割り圓おたす矎しいずスマヌト、矎しいず愚か、stいずスマヌト、ず愚か。

実際、補品の普遍射は射の生成物です。

さたざたな圢匏の䜜業は、さたざたなプログラミング蚀語で実装されおいたす。 これらは、構造、タプル、およびSQL、LINQなどのあらゆる皮類の結合です。 types-worksに぀いお読んでください。

JavaScriptでは、䜜品の暙準的な投圱はデストラクタたたはアクセサず芋なすこずができたす。

 monkeyKind.a monkeyKind.b 

コンストラクタヌずしおの普遍射

 function u(x) { return { a : isBeautiful(x), b : isSmart(x) }; } 

カテゎリ理論では、アクセッサはデストラクタず呌ばれるこずがよくありたす。これは、耇雑なオブゞェクトを構成芁玠に解析できるため、デザむナず重耇しおいたす。 そのようなデストラクタを呌び出す堎合、オブゞェクトをたったく砎棄する必芁はありたせん。

金額


オブゞェクトX jの合蚈は、オブゞェクトXず射圱i j X j →Xであり、正準埋め蟌みず呌ばれ、任意のオブゞェクトYず射圱f j X j →Yに察しお、u X X i j = f j 。

2぀のオブゞェクトの可換図の䟋


セットのカテゎリでは、オブゞェクトの合蚈はセットの遞蚀的結合です。 ぀たり 結合されたセットに䞀臎するオブゞェクトがある堎合、これらのオブゞェクトはマヌゞされたせんが、倧たかに蚀えば、各オブゞェクトがどのセットからのものであるかを理解できるように、䜕らかの方法でマヌクされたす。


集合論では、遞蚀的和集合の芁玠は通垞、たずえば1 A 、2 A 、3 A 、a B 、b Bなど、いく぀かのタグたたはむンデックスでマヌクされたす。 しかし、この䟋では、合蚈の芁玠は1〜5の単玔な数字であり、射圱fずgによっお元のセットの芁玠に関連付けられおいたす。 そしお、和の芁玠を「ラベル付け」するのはたさにこれらの射である。 䜜品に関しおは、射のない集合自䜓は特別な圹割を果たしたせん。

明らかに、積ず合蚈は二重の抂念です。 それらは、射の反転たで同様に定匏化されたす。

しかし、䞀般化はそこで終わりたせん。 補品ず量は、それぞれ最終オブゞェクトず初期オブゞェクトに非垞に䌌おいたす。 䜜品および有限オブゞェクトの堎合、特定の条件を満たすカテゎリの各オブゞェクトから普遍型を䜜成するこずができたす-このような構成は制限ず呌ばれたす 。 和オブゞェクトず初期オブゞェクトの堎合、特定の条件を満たすカテゎリの各オブゞェクトに察しお普遍射を構築するこずができたす-そのような構造はcolimitsず呌ばれたす 。 さらに、制限ず共同制限の䟋がさらに衚瀺されたす。

䞀般的な堎合、co制限は、ある図に察しお定矩されたcoコヌンです。 私が蚀ったように、チャヌトは、あるむンデックスカテゎリから珟圚のカテゎリぞのファンクタヌです。 おおたかな堎合は、むンデックスカテゎリによっおダむアグラムの「フォヌム」、「倖芳」が決定され、最終的に取埗する共同制限最終オブゞェクト、補品などが決定されたす。 このアむデアをさらに発展させるず、カコドモンを匕き起こすリスクが生じたす。



芁するに、アむデアは、䞊蚘で怜蚎したような䞀般的な抂念でさえ、さらに匷力に䞀般化できるずいうこずです。

, , , () «» . .

().
 SetCategory.prototype.coproduct = function (A, B) { return new SetCoproduct(this).calculate(A, B); }; function SetCoproduct(cat) { this.cat = function () { return cat; }; } SetCoproduct.prototype.calculate = function (A, B) { this.obj = new Set(); var elementCount = 1; function createInjection(set, obj) { var mapping = {}; set.forEach(function (x) { obj.add(elementCount); mapping[x] = elementCount; elementCount++; }); return mapping; } this.f = this.cat().morphism(A, this.obj, createInjection(A, this.obj)); this.g = this.cat().morphism(B, this.obj, createInjection(B, this.obj)); return this; }; SetCoproduct.prototype.univ = function(m, n) { assertEqualCodom(m, n); assertEqualDom(this.f, m); assertEqualDom(this.g, n); var obj = m.codom(); var mapping = {}; function addMappings(f, h) { h.dom().forEach(function (x) { mapping[f.image(x)] = h.image(x); }); } addMappings(this.f, m); addMappings(this.g, n); var u = this.cat().morphism(this.obj, obj, mapping); assertCommutes(u.compose(this.f), m); assertCommutes(u.compose(this.g), n); return u; }; 

, .


, , – . – .

, , – . - . . , . JavaScript , .

– – :

 function Chimpanzee() { } function Gorilla() { } 

p, – q, – C. , C – : , , . p , , q :

 function u(x) { if (x instanceof Chimpanzee) { return p(x); } else if (x instanceof Gorilla) { return q(x); } } 

( )


- , - . , , ? , , coproduct complement. . , , .

A+B, A i 1 . i 1 , A, – A+B. i 2 , :


.
 SetCategory.prototype.coproductComplement = function (f) { return new SetCoproduct(this).complement(f); }; SetCoproduct.prototype.complement = function (f) { this.obj = f.codom(); this.f = f; this.g = this.cat().morphism(f.codom().diff(f.image()), this.obj).initId(); return this; }; 

N-, . . .


() ( ) ( ). () , .. .

f, g : X → Y – E eq : E → X, f ∘ eq = g ∘ eq O m : O → X f ∘ m = g ∘ m, u : O → E, eq ∘ u = m, .. .



 . - . . -, , , . , , . , . -, , . - . .

f ∘ eq = g ∘ eq. X eq , f g .


f g «1» X «a» Y. , eq «1» E «1» X, f(eq(1)) = g(eq(1)) = a. , , «1» E, Y.

f «2» «a», g «2» «b». , eq, «2» X . ぀たり f(eq(?)) = a g(eq(?)) = b, «a» «b».

X Y E eq. «1» «3» f g .

, E eq - f g. O m u? , E eq, , . O m, f ∘ m = g ∘ m.


, m f g , eq. eq m? . , E eq , O m , , . , , , , . - , , .

, ? . E O h, m ∘ h = eq, {(1,1),(3,3)} {(1,2),(3,3)}. , , O m , .

, , E eq - . O m u = {(1,1),(2,1),(3,3)}. O m, f ∘ m = g ∘ m, , .

O m E eq? ? , .

, , JavaScript! , , , ().

(), .
 SetCategory.prototype.equalizer = function (f, g) { return new SetEqualizer(this).calculate(f, g); }; function SetEqualizer(cat) { this.cat = function () { return cat; }; } SetEqualizer.prototype.calculate = function (f, g) { assertParallel(f, g); this.f = function () { return f }; this.g = function () { return g }; var dom = new Set(); var codom = f.dom(); this.q = this.cat().morphism(dom, codom); f.dom().forEach(function (x) { if (f.image(x) == g.image(x)) { dom.add(x); this.q.push(x, x); } }.bind(this)); this.obj = this.q.dom(); assertCommutes(f.compose(this.q), g.compose(this.q)); return this; } SetEqualizer.prototype.univ = function (m) { assertEqualCodom(this.q, m); assertCommutes(this.f().compose(m), this.g().compose(m)); var mapping = {}; m.forEach(function (x, y) { mapping[x] = this.q.preimage(y).representative(); }.bind(this)); var u = this.cat().morphism(m.dom(), this.obj, mapping); assertCommutes(this.q.compose(u), m); return u; }; 

. , – . , f ∘ eq = g ∘ eq f ∘ m = g ∘ m 
 . , , ? .

f = g. , , , f g. , , , . , . f g , eq ( ).

, ? . O E . , , – ( ), , .

? , «» , (, ) . , , .


f, g : X → Y – Q q : Y → Q, q ∘ f = q ∘ g O m : Y → O m ∘ f = m ∘ g, u : Q → O, u ∘ q = m, .. .


, , . , , , , .

.


f g, , «1» X «a» Y. q(f(1)) = q(g(1)), , q «a» «a» Q.

f «2» «b», g «2» «c». q(f(2)) = q(g(2)), q «b» «c» «b» Q. , «b» «c» «b».

f «3» «c», g «3» «d». , , «c» «d» . «c» «b», , «d» «b».

«e» «e» «f». Q q.

, , O m, m ∘ f = m ∘ g. , O m , Q q.


O m , , , Q q. , , «a» «b», «1».

, . – . , () .

, .
 SetCategory.prototype.coequalizer = function (f, g) { return new SetCoequalizer(this).calculate(f, g); }; function SetCoequalizer(cat) { this.cat = function () { return cat; }; } SetCoequalizer.prototype.calculate = function (f, g) { assertParallel(f, g); this.f = function () { return f }; this.g = function () { return g }; var dom = f.codom(); var codom = new Set(); var eq = {}; f.dom().forEach(function (x) { var fx = f.image(x); var gx = g.image(x); eq[fx] = eq[gx] = has(eq, fx) ? eq[fx] : has(eq, gx) ? eq[gx] : fx; }); this.q = this.cat().morphism(dom, codom); dom.forEach(function (s) { var t = eq[s] || s; codom.add(t); this.q.push(s, t); }.bind(this)); this.obj = this.q.codom(); assertCommutes(this.q.compose(f), this.q.compose(g)); return this; } SetCoequalizer.prototype.univ = function (m) { assertEqualDom(this.q, m); assertCommutes(m.compose(this.f()), m.compose(this.g())); var mapping = {}; m.dom().forEach(function (x) { mapping[this.q.image(x)] = m.image(x); }.bind(this)); var u = this.cat().morphism(this.q.codom(), m.codom(), mapping); assertCommutes(u.compose(this.q), m); return u; }; 

– . : , , . . .

( )


. , , ? – .

f : X → Z g : Y → Z – P p : P → X q : P → Y, f ∘ p = g ∘ q Q m : Q → X n : Q → Y, f ∘ m = g ∘ n, u : Q → P, p ∘ u = m q ∘ u = n, .. .


, - :


, P X Y, , , , f g Z.

, , , .

.
 CompleteCategory.prototype.pullback = function (f, g) { return new Pullback(this).calculate(f, g); }; function Pullback(cat) { this.cat = function () { return cat; }; } Pullback.prototype.calculate = function (f, g) { assertEqualCodom(f, g); this.f = f; this.g = g; var prod = this.cat().product(f.dom(), g.dom()); this.product = function () { return prod; }; var eq = this.cat().equalizer(f.compose(prod.f), g.compose(prod.g)); this.equalizer = function () { return eq; }; this.p = prod.f.compose(eq.q); this.q = prod.g.compose(eq.q); this.obj = eq.obj; assertCommutes(this.f.compose(this.p), this.g.compose(this.q)); return this; } Pullback.prototype.univ = function (m, n) { assertEqualDom(m, n); assertEqualCodom(m, this.p); assertEqualCodom(n, this.q); var u = this.equalizer().univ(this.product().univ(m, n)); assertCommutes(this.p.compose(u), m); assertCommutes(this.q.compose(u), n); return u; }; 

. X Y, f ∘ π 1 g ∘ π 2 . – P . p π 1 ∘ eq, q – π 2 ∘ eq. .


, : , , .. , , , . , . , , .

( )


f : Z → X g : Z → Y – P p : X → P q : Y → P, p ∘ f = q ∘ g Q m : X → Q n : Y → Q, m ∘ f = n ∘ g, u : P → Q, u ∘ p = m u ∘ q = n, .. .


i 1 ∘ f i 2 ∘ g, i 1 i 2 – X Y. p q h ∘ i 1 h ∘ i 2 , h – :


, P – X Y, , Z, :


. , «a» «b» X Y P «1» «2» . «c» X «d» Y. «c» Y .

. g q. f p, X P , Y. . .

, (, , ) , :

.
 CocompleteCategory.prototype.pushout = function (f, g) { return new Pushout(this).calculate(f, g); }; function Pushout(cat, f, g) { this.cat = function () { return cat; }; } Pushout.prototype.calculate = function (f, g) { assertEqualDom(f, g); this.f = f; this.g = g; var cp = this.cat().coproduct(f.codom(), g.codom()); this.coproduct = function () { return cp; }; var ceq = this.cat().coequalizer(cp.f.compose(f), cp.g.compose(g)); this.coequalizer = function () { return ceq; }; this.p = ceq.q.compose(cp.f); this.q = ceq.q.compose(cp.g); this.obj = ceq.obj; assertCommutes(this.p.compose(this.f), this.q.compose(this.g)); return this; } Pushout.prototype.univ = function (m, n) { assertEqualCodom(m, n); assertEqualDom(m, this.p); assertEqualDom(n, this.q); var u = this.coequalizer().univ(this.coproduct().univ(m, n)); assertCommutes(u.compose(this.p), m); assertCommutes(u.compose(this.q), n); return u; }; 


, , , JavaScript ML:
» DE Rydeheard, RM Burstall. Computational Category Theory, 1988

, :
» Hans JÌrgen Schneider. Graph Transformations. An Introduction to the Categorical Approach, 2011

, , , , , :
» Peter Smith, Category Theory. A Gentle Introduction, 2016

, :
» Maarten M. Fokkinga. A Gentle Introduction to Category Theory — the calculational approach, 1994

, :
» Andrea Asperti, Giuseppe Longo. Categories, Types and Structures. Category Theory for the working computer scientist, 1991
» Michael Barr, Charles Wells. Category Theory for Computing Science, 1998

, « » ( — Bartosz Milewski ), , , , . , .

. , , . , . — . , , . , , , 1- :
» Michael Barr, Charles Wells. Toposes, Triples and Theories, 1985

, , David I. Spivak . , .

:
» Michael J. Healy. Category Theory Applied to Neural Modeling and Graphical Representations, 2000

おわりに


. , , , . , .

, . . , Haskell Hask. . , , . . . - .

. , , , . . , , , .

, – , , .

.

-, , . , calcCartesianProduct(), - multiplyFunctions(). , , — . ぀たり .

-, , , .

-, , . , ( assert ). , - , !

, , . , , , , . , . «», .

, - JavaScript.

. , .

» .

Source: https://habr.com/ru/post/J313254/


All Articles