Hask
ファンクターの定義を圏論からハスケルの定義に次のようにマッピングすることができました:のオブジェクトは型であるため、ファンクターF
a
をHask
新しいタイプにマップしますF a
。a -> b
をHask
新しい射にマップF a -> F b
しfmap :: (a -> b) -> (f a -> f b)
ます。ここまでは順調ですね。今、私はに行きますApplicative
、そして教科書でそのような概念の言及を見つけることができません。それが追加されます何を見ることでFunctor
、ap :: f (a -> b) -> f a -> f b
私は自分の定義を思い付くことを試みました。
まず、(->)
もタイプなので、の射もそのHask
対象であることに気づきました。これに照らして、適用可能なファンクターは、ソースカテゴリの「矢印」オブジェクトを宛先カテゴリの射にマッピングすることもできるファンクターであると提案しました。
これは正しい直感ですか?より正式で厳密な定義を提供できますか?
適用可能なファンクターを理解するための鍵は、それらがどのような構造を保持しているかを理解することです。
通常のファンクターは、基本的なカテゴリー構造を保持します。つまり、カテゴリー間でオブジェクトと射をマップし、カテゴリーの法則(結合性と同一性)を保持します。
ただし、カテゴリにはさらに構造がある場合があります。たとえば、射に似ているが複数の引数を取るマッピングの定義を許可する場合があります。このようなマッピングは、カリー化によって定義されます。たとえば、2つの引数の関数は、1つの引数が別の関数を返す関数として定義されます。これは、関数型を表すオブジェクトを定義できる場合に可能です。一般に、このオブジェクトは指数関数と呼ばれます(Haskellでは、これは単なる型ですb->c
)。次に、1つのオブジェクトから指数関数への射を持ち、それを2引数の射と呼ぶことができます。
Haskellの適用可能なファンクターの伝統的な定義は、複数の引数の関数をマッピングするという考えに基づいています。しかし、異なる境界に沿って複数引数関数を分割する同等の定義があります。製品(Haskellのペア)から別のタイプ(ここではc
)へのマッピングなどの関数を見ることができます。
a -> (b -> c) ~ (a, b) -> c
これにより、アプリケーションファンクターを製品を保存するファンクターと見なすことができます。しかし、製品はいわゆるモノイド構造の一例にすぎません。
一般に、モノイド圏はテンソル積と単位オブジェクトを備えた圏です。Haskellでは、これは、たとえば、デカルト積(ペア)とユニットタイプである可能性があります()
。ただし、モノイド法則(結合法則と単位法則)は同型写像までしか有効ではないことに注意してください。例えば:
(a, ()) ~ a
次に、適用可能なファンクターは、モノイド構造を保持するファンクターとして定義できます。特に、ユニットと製品を保存する必要があります。ファンクターを適用する前または後に「乗算」を実行するかどうかは関係ありません。結果は同形である必要があります。
ただし、本格的なモノイダル関数は必要ありません。必要なのは、(同型ではなく)2つの射です。1つは乗算用、もう1つは単位用です。モノイド構造を半分保存するこのようなファンクターは、緩いモノイダルファンクターと呼ばれます。したがって、代替定義:
class Functor f => Monoidal f where
unit :: f ()
(**) :: f a -> f b -> f (a, b)
とMonoidal
同等であることを示すのは簡単Applicative
です。例えば、我々が得ることができますpure
から、unit
その逆:
pure x = fmap (const x) unit
unit = pure ()
適用法は、モノイド法(結合法則と単位法則)の保存から単純に続きます。
圏論では、モノイド構造の保存はテンソル強度に関連しているため、適用可能なファンクターは強い緩いモノイダルファンクターとしても知られています。ただし、Haskでは、すべてのファンクターが製品に関して標準的な強度を持っているため、このプロパティは定義に何も追加しません。
さて、モナドをエンドファンクターのカテゴリーのモノイドとして定義することに精通している場合は、Applicativeが同様に、テンソル積が日の畳み込みであるエンドファンクターのカテゴリーのモノイドであることを知りたいと思うかもしれません。しかし、それを説明するのははるかに困難です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加