generated at
関手とFunctor

関手Functor型クラスの対応について
HaskellのFunctor型クラスが、圏論で言う関手に対応する



関手の定義
\mathscr{A},\mathscr{B}を圏としたとき以下からなる
D1 :A\to F(A)
\mathrm{ob}(\mathscr{A})\rightarrow\mathrm{ob}(\mathscr{B})
D2 :f\to F(f)
\mathscr{A}(A,A')\rightarrow\mathscr{B}(F(A),F(A'))
以下を満たす
T1 : F(1_A)=1_{F(A)}
T2 : F(f\circ g)=F(f)\circ F(g)
後で参照しやすいように D1 , D2 , T1 , T2 と名前を振っておいた



Functor型クラスの定義
hs
class Functor f where fmap :: (a -> b) -> f a -> f b
-> は右結合なので以下のように括弧を付与できる
fmap :: (a -> b) -> (f a -> f b)


関手は、定義からわかるように2つの圏を見たときに、
対象同士と
射同士の
2つの対応付けを同時に行うものである
HaskellにおけるFunctorについてもこの2つの対応があることを確認する


具体的な対応例を見るとこんな感じになる
Hask圏のことを考えているので、ドメインもコドメインもHask圏になる
その対象としての型 Char , Int , [Char] , [Int]
射としての関数 ord :: Char->Int
関手としてのFunctor List fmap がある
Functor :: Hask -> Hask になるのでHaskellのFunctorは関手の中でも特に自己関手限定の話である
ここで
*->* なFunctor(ここではList)」が「 * の型同士」の対応付け、
(a -> b) -> f a -> f b な関数 fmap 」が「関数同士」の対応付け
をしていることがわかる
なので、両方ともHask圏の対象同士、射同士を同時に対応付けている
圏論風に書くと
f :: Int -> Char は、
List f :: List Int -> List Char になっている
この List f というのが、Haskellで言う fmap f なのである
カインドが *->* な型コンストラクタだけを考えるだけではダメなんだなmrsekut
Functorにするために、
そのただの型コンストラクタに、
fmap の実装を強制することによって、
初めてその型コンストラクタが関手たりうる。
だから、ただの多相な型 Human a のような型コンストラクタはFunctorではない


関手の定義の T1 , T2 の部分がFunctor則に対応する
hs
fmap id == id -- T1 fmap (f . g) == fmap f . fmap g -- T2



一応ListがFunctor則を満たすことを確認する
hs
fmap id [1,2,3] == [1,2,3] id [1,2,3] == [1,2,3] f = (+ 1) g = (* 2) fmap (f . g) [1,2,3] == [3,5,7] (fmap f . fmap g) [1,2,3] == [3,5,7]
↓これ書く意味あるのか?
T1.hs
fmap id [] == [] fmap id (x:xs) == id x : map id xs == x : map id xs
T2.hs
fmap (g . f) [] == [] fmap (g . f) (x:xs) == (g . f) x : map (g . f) xs


参考
Hask圏以外の圏のFunctorを作る