圏論では、関手は2つの圏間の準同型です。Haskellでは、アプリケーションファンクターを使用すると、「ファンクター内」で関数を適用できると言われています。「ファンクター内で機能する」という言葉を数学に翻訳したり、他の洞察を与えたりすることはできますか?(ファンクターはなどである可能性があることを私は知っていますがMaybe
、[]
それでもその概念を理解するのに苦労しています。)
2 に答える
私の圏論はまったく強力ではありません(私はHaskellのプログラミング側から始めて、最近、いくつかの概念のいくつかの圏論の基礎を学ぼうとしています)。しかし、これが私が持っているものです:
Haskellでは、ファンクターは型コンストラクターです。つまり、一般的なタイプから「ファンクターのタイプ」にマップされます。
圏論では、ファンクターはあるカテゴリーのオブジェクトから別のカテゴリーのオブジェクトにマップします。
圏論をHaskellに適用するとき、私たちはHaskellタイプのカテゴリーであるHaskのカテゴリーで作業していると想像します。
したがって、Haskellファンクターは一般的な圏論ファンクターではありません。それらはすべてHaskからHaskのサブカテゴリにマップされます(一部のファンクターのタイプと任意のタイプは依然としてHaskellタイプであるため)。たとえば、ファンクターはHaskのオブジェクト(タイプ)をフォームのタイプのカテゴリーにマップします。f a
f
a
Maybe
Maybe a
関数はHaskellのファーストクラスであるため、関数型は完全に通常の型であり(Haskのオブジェクトです)、ファンクターは関数型を「ファンクターの関数型」にマップします。したがって、「ファンクター内の関数」という句は、ファンクターを関数型に適用した結果として生じる型の値の省略形です。たとえばJust (+1)
、タイプの1つの特定の値です。これは、ファンクターがオブジェクトMaybe (Int -> Int)
をマップするオブジェクト(タイプ)です。Maybe
Int -> Int
したがって、「適用ファンクター」は、ファンクターの「宛先」カテゴリーのオブジェクトであるタイプの関数である値を取得し、それらの値を宛先カテゴリーのタイプの他の値に適用するのに十分な、いくつかの追加のルールを持つファンクターです。 。
もう一度例として使用すると、オブジェクトと、の間、オブジェクトと、の間、およびオブジェクトと。のMaybe
間の対応を与えるのはファンクターであることがわかっているだけです。ただし、値inと値inを取り、値inを生成する機能はありますが、ファンクターであることは、値inと値inを使用して対応する操作を実行できることを保証するものではありません。Int -> Char
Maybe (Int -> Char)
Int
Maybe Int
Char
Maybe Char
Int -> Char
Int
Char
Maybe
Maybe (Int -> Char)
Maybe Int
それが適用可能なファンクターであることもわかっている場合、値を取り、値を取り、値Maybe (Int -> Char)
をMaybe Int
生成する機能があります。これは、値を値Maybe Char
に適用する際の特定のプロパティを満たします。Int -> Char
Int
私の知る限り、応用関手は純粋な圏論の観点からはそれほど興味深いものではありません。おそらくこれは、圏論がHaskellの型に対応するオブジェクト間の関係に関係しているためですが、プログラミングの観点からは、適用可能なファンクターはそれらの型の値間の関係によって動機付けられていますか?(ファンクターを使用して取得した「関数型」の値を、計算を行うものに引き続き適用できるようにする必要があります)。
数学に戻る翻訳
モノイド閉圏には、射の関係を「内在化」する「指数」の概念があります。次に、これらの指数を評価できます。つまり、あなたには言い方があります(すみません、Stackoverflowにはmathjaxがありません)
eval : (a ~> b,a) -> b
カリー化とカリー化のメタ操作も同様です。
「適用可能なファンクター」は、「適用可能な」方法で指数をマップし、F (a ~> b)
と組み合わせてF a
を取得できF b
ます。これは、適用ファンクターがモノイダルファンクターであるため、(ターゲットカテゴリで)操作が行われるためです。
f a -> f b -> f (a,b)
これは、fmapevalもap
Haskellから提供されます。
それが役に立ったとは思えませんが、
ハスケル
適用可能なファンクターを理解するための最良の方法は、タイプを調べることです。
class Functor f => Applicative f where
pure :: a -> f a
<*> :: f (a -> b) -> f a -> f b
ささいな例は
newtype Id a = Id a
instance Applicative Id where
pure a = Id a
Id f <*> Id a = Id (f $ a)
Id
もMonad
です。実際、すべてMonad
のはApplicative
です。
pure = return
mf <*> mx = do f <- mf
x <- mx
return (f x)
より興味深い例は無限のシーケンスです
data Seq a = Seq a (Seq a)
instance Applicative Seq where
pure a = Seq a (pure a)
(Seq f fs) <*> (Seq x xs) = Seq (f x) (fs <$> xs)
これはリスト上のものと同等であると考えることができzipWith $
ます。すべてMonad
がApplicative
ですが、対応するモナドインスタンスは...明白ではない(そしてかなり遅い)ので、無限のシーケンスは楽しいと思います。それは読者への演習として残されます(ところで、私はこの例/演習を、pigworkerがこのサイトに書いたと思うことを読んだことを覚えているものから作り上げています)。