3
応用数学解説
文献あり

圏論から見るHaskellのFunctor

2119
0

はじめに

きっかけは、先月Qiitaに投稿された次の記事を読んだことです。

HaskellにおけるFunctor => Applicative => Monadの継承関係についての考察記事ですが、これを圏論的な視点からアプローチしなおしてみようと思ったのが当初の目的でした。しかし、そのために調べ物をしていると、あまりにも自分がapplicative functorについて知らないということが発覚してしまい、記事の内容を大幅に変更したものが本記事です。

本記事ではHaskellにおけるFunctorが果たす役割を圏論的なアプローチで考察します。 Haskell Advent Calendar に参加しようとも思っていたのですが、土壇場で熱を出して数日寝込んだために全ての予定が四散してしまいました。南無。

前提知識について

本記事では圏論の以下の知識を前提として書いていきます。これら基礎知識については Leinster Mac Lane の対応する章、あるいは alg-dさんの圏論のページ などをご参照ください。

  • 圏・関手・自然変換の定義 (Chap.1, [Leinster]、または ~I.§4, [MacLane])

また、例示部分に限ってはさらに追加の知識が必要になるかもしれません。ご了承ください。もしいい例をご存じの方がいましたらご教示いただけると幸いです。

圏論的に見たプログラミング

プログラムと型と圏論の関係

型 (の組)、あるいはその型の値の集合を対象として、変数の組x1:A1,,xn:Anから型Bの値を返すプログラムf(A1,,An)からBへの射とみなすことで、これらの型とプログラムは圏をなします。これはものすごく端折って書いているので厳密にはいろいろ設定をちゃんとしないといけないのですが、今回は置いておきます。

型とプログラムで圏を構成できるということは、型付きのプログラムを行う体系は圏論によって抽象的な議論が可能ということになります。あるいは、圏論を通して意味論を様々考えることができるようにもなります。

カルテシアン積

一般的なラムダ計算の体系において、その圏論的意味論にはカルテシアン閉圏が採用されます。カルテシアン閉圏とは、終対象1とカルテシアン積×が存在して、さらに任意の内部hom対象ABを持つ圏のことです。

  1. C終対象1とは、任意の対象xCに対して!x:x1がただ1つ存在するようなCの対象1である。
  2. Cカルテシアン積を持つとは、任意の対象x1,x2Cに対して対象x1×x2と各成分への射x1p1x1×x2p2x2が存在して、任意のx1f1af2x2に対してfi=piuを満たすu:ax1×x2がただ1つ存在することである。
  3. Cのカルテシアン積に対して、内部hom対象ABとは、evA,B:AB×ABを備えた対象ABであって、任意のf:C×ABに対してf=evA,B(f×idA)を満たすf:CABがただ1つ存在するものである。
  4. 終対象・カルテシアン積・内部hom対象を備えた圏をカルテシアン閉圏という。

Haskellで言うと、終対象とは():()、カルテシアン積とは(a,b):(A,B)のことです。また、内部hom対象とは関数型ABのことです。終対象とカルテシアン積を持つ圏は全ての有限積を持ちます。これはHaskellでは(), Solo , タプル(a1,,an)に相当します。

圏論的に見たFunctor

関手とFunctor

HaskellにおけるFunctorとは、型演算ATAであって、メソッドとしてfmap:(αβ)TαTβを持つものをいいます。加えて、Functor Tには次の2つの公理を満たすことが期待され、これは言語仕様などでは定められていませんが、実装によって公理は満たされているものとして扱われます。

  • 単位元律 fmap(idA)=idTA
  • 合成律 fmap(gf)=fmap(g)fmap(f)

Tが関手であればこの2つの公理は当然に満たされますが、逆にTが関手であってもfmapの実装が自然になされるわけではありません。これは、fTfという対応は一般に圏の内側で定義されているものではないからです。

fmapを射として持たない例

可換モノイドとその間のモノイド準同型からなる圏CMonについて考える。このとき、ただ1つの元からなる自明なモノイドが終対象、通常の直積がカルテシアン積となり、(fg)(x)=f(x)g(x)によってモノイド準同型による可換モノイドが構成できるため、CMonはカルテシアン閉圏である。

任意の可換モノイド(M,e,)に対して、TM=M{0} (0M) として、二項演算¯:TM×TMTM
m¯m=mm(m,mM)m¯0=m(mM)0¯0=0
で定める。

このとき、モノイド準同型f:MNに対してTf:TMTN
(Tf)(m)=f(m)(mM)(Tf)(0)=0
で定まり、T(idM)=idTMT(gf)=TgTfを満たすため、Tは関手である。

一方で、fTf(MN)(TMTN)のモノイド準同型ではなく、従ってCMonfmapに相当する射を持たない。

強自己関手

fmapを備えた自己関手は、強自己関手と呼ばれる特別な関手のクラスに一致します。歴史的には、これは豊穣圏におけるモナドの研究から生まれた概念であり、おそらく初出はA.コック (Andres Kock) の1970年の論文です。

対称モノイダル閉圏(C,I,,)上の強自己関手 (strong endofunctor) とは、CからCへの関手で、かつC-豊穣関手でもあるものを言う。

すなわち、強自己関手T=(T,stT):CCとは関手T:CCCの射の族
stA,BT:(AB)(TATB)
の組であり、次の2つの図式を可換にするものである:
(BC)(AB)stB,CFstA,BFA,B,C(TBTC)(TATB)TA,TB,TC(AC)stA,CF(TATC)
IjAjTA(AA)stA,AF(TATA)
ここでA,B,C:(BC)(AB)(AC)とは2つの関数の合成、jA:I(AA)とは(AA)の要素としてのidAを示す射である。

本稿ではモノイダル圏や豊穣圏については立ち入らず、強自己関手の定義も後半の言い換えたものを使います。カルテシアン閉圏は対称モノイダル閉圏の特別な場合なので、以降カルテシアン閉圏と直積で書きます。モノイダル圏や豊穣圏についてどうしても気になる場合は、以下の文献を参考にしてください。

  • 対称モノイダル閉圏:[MacLane]のⅦ.1,Ⅶ.7、または §E.2, [ Riehl ]
  • 豊穣圏:[MacLane]のⅠ.8、あるいは概観だけなら、 このセミナー動画 の最初5分を見るのが一番早いと思います。

C上の強自己関手T、すなわちfmapを備えた関手Tについて、次のような射が定義できます:
τA,B=λ(a,r).fmap(λb.(a,b))(r):A×TBT(A×B)
τA,BA,Bについて自然で、さらに次のような図式を可換にします:
(A×B)×TCτA×B,CT((A×B)×C)A×(B×TC)idA×τB,CA×T(B×C)τA,B×CT(A×(B×C))
1×TAτ1,AT(1×A)TA

逆に、上記の2つの図式を可換にするA,Bについて自然な射の族τA,B:A×TBT(A×B)を持つ性質のことを、テンソル強性 (tensorial strength) と言います。モノイダル圏Cがテンソル強性を持つとき、stA,BT:(AB)(TATB)を次の射のカリー化として定義できます:
(AB)×TAτAB,AT((AB)×A)TevA,BTB
ここでevA,B:(AB)×ABとは関数適用を表す射です。

実は、定義2の図式を可換にするstA,BT:(AB)(TATB)が定まっているとき、Tは対象上の写像ATAでありさえすればTの関手性が示せます (Tf=fmap(f)とすればよい)。このことから、ATAの対応とfmapの実装のみによってFunctorクラスを定められることがわかります。

Const型のFunctor性

Const 型はConst a b = Const { getConst :: a }で定義されるデータ型です。この型についての説明には

The 'Const' functor.

とあり、本質的には型aの値を保持したままFunctorのように振る舞う存在であると思われます。実際、Functorのインスタンスが次のように実装されます:

      instance Functor (Const a) where
    fmap _ (Const v) = Const v
    

Const aはaがMonoidのインスタンスである場合のみApplicativeのインスタンスが実装されています。これは、型Const a (x -> y)の値と型Const a xの値から型Const a yの値を作るに際して、それぞれの値が持つ型aのデータの処理を、Applicativeの公理を満たしながら行うことができないためと思われます。

Applicativeへの動機

強関手は関手よりは強い概念ですが、プログラミングの上では基礎的な構造以上の有用性を持っていません。具体的にはATAT(AB)TATBといった計算が、Functor上では保証されないためとても不便です。

そのような計算を保証した構造が、HaskellのApplicative、圏論ではapplicative functorと呼ばれるものです。

圏論から見るHaskellのApplicative へ続く →

参考文献

[1]
Andres Kock, Monads on Symmetric Monoidal Closed Categories, Archiv der Mathematik, 1970, pp. 1–10
[2]
Tom Leinster (著), 斉藤恭司 (監修), 土岡俊介 (訳), ベーシック圏論 普遍性からの速習コース (Basic Category Theory), 丸善出版, 2015
[3]
S. Mac Lane (著), 三好博之, 高木理 (訳), 圏論の基礎 (Categories for the Working Mathematician), 丸善出版, 2012
[4]
Emily Riehl, Category Theory in Context, Aurora: Modern Math Originals, Dover Publications, 2016
投稿日:20211216
更新日:20231123
OptHub AI Competition

この記事を高評価した人

高評価したユーザはいません

この記事に送られたバッジ

バッジはありません。
バッチを贈って投稿者を応援しよう

バッチを贈ると投稿者に現金やAmazonのギフトカードが還元されます。

投稿者

merliborn
merliborn
36
9826
圏論や普遍代数に興味があります。現在の専門は型理論および圏論的意味論です。

コメント

他の人のコメント

コメントはありません。
読み込み中...
読み込み中
  1. はじめに
  2. 前提知識について
  3. 圏論的に見たプログラミング
  4. プログラムと型と圏論の関係
  5. カルテシアン積
  6. 圏論的に見たFunctor
  7. 関手とFunctor
  8. 強自己関手
  9. Applicativeへの動機
  10. 参考文献