Her şeyden önce:
Herhangi bir monad aynı zamanda bir uygulama fonktörüdür ve herhangi bir uygulama fonktörü bir fonktordur.
Bu, Haskell bağlamında doğrudur, ancak ( Applicative"güçlü gevşek monoidal functor" olarak okumak ) genel olarak değil, farklı monoidal kategoriler arasında "uygulanabilir" functorlara sahip olmanız önemsiz bir nedenden ötürü, monadlar (ve komonadlar) endofunktörlerdir. .
Ayrıca, Applicativegüçlü gevşek monoidal functorlarla tanımlamak biraz yanıltıcıdır, çünkü adın (ve tip imzasının (<*>)) haklı gösterilmesi, hem monoidal yapıyı hem de dahili homu koruyan kapalı monoidal kategoriler arasında bir functor gerektirir . Bu, her iki özelliği koruyan monoidal kapalı kategoriler arasındaki bir functorun diğerini bariz şekilde koruduğu durumlar dışında buna "gevşek kapalı monoidal functor" denebilir . Çünkü sadece Hask üzerindeki monofonik yapısını koruyan endofunktörleri açıkladığı için , örnekleri , bu şekilde atılabilecek mukavemetleri de dahil olmak üzere otomatik olarak birçok özellik kazanır.Applicative(,)
Görünen bağlantı Monad, tartışmasız Applicative, ilgili monoid yapılarının yönlerinin çakışmasına neden olan örtülü sınırlamaların bir artefaktı, maalesef dualizasyondan sağ çıkamayan mutlu bir tesadüf.
Bir kategorisindeki bir komoderin C o p üzerindeki bir monad olması gibi , bir oplax monoidal functor C → D bir lax monoidal functor C o p → D o p'dir . Ama H a sCCop C→DCop→Dop monoidalkapalıdeğildirvefonksiyon uygulaması içermeyenbirkoliismi pek hak etmez. Her neyse, sonuç çok ilginç olmayacaktı:HaskopApplicative
class (Functor f) => CoMonoidal f where
counit :: f () -> ()
cozip :: f (a, b) -> (f a, f b)
Bunun yerine "kolaks kapalı functor" kavramını hayal edebiliriz, ki bu daha çok Applicativevarmış gibi görünecektir . Ne yazık ki, hiç kapalı bir kategori (benim en iyi bildiğim için) değil: in H a s k karşılık Morfizm için b → bir de H a s k o p , ancak bir olarak çalışmaya değil iç hom orada - oklar tersine çevrildiğinden, bunun yerine genel olarak H a s k için tanımlayamadığımız bir tür işbirliği işlevi gerekecektir .Haskopnewtype Op b a = Op (a -> b)Haskb→aHaskopOp b aHask
için "kolaks kapalı functorlar" ın var olduğunu ve ayrıca saf bir şekilde umduğumuz gibi çalıştığını iddia edersek , buna dayanan bir ortak muhtemelen şöyle görünecektir:HaskApplicative
class (Functor f) => CoApplicative f where
copure :: f a -> a
coap :: (f a -> f b) -> f (a -> b)
Ekleme duplicate :: f a -> f (f a)için copurebir comonad üretecektir elbette (kanunlarını varsayarak tatmin edilir). Ancak - ne coapolursa olsun - ve arasında açık bir ilişki yoktur extend :: (f a -> b) -> f a -> f b. Tiplerin karşılaştırılması, dualizasyonun farklı şekillerde gerçekleştiği açıktır: altta yatan duplicateve cozipbirbirleriyle veya birbirleriyle coap(muhtemelen hiçbir şekilde anlam ifade etmemektedir) olan liftA2 (,)ve (<*>)bunlarla eşdeğer olan ve türetilebilen ortak yapıların çok az olduğu açıktır join.
Komonadlarla Applicativedaha da az ilgisi olan bir çiftleştirmenin olası başka bir yolu, kontravaryant monoidal fonksiyonları düşünmektir:
class (Contravariant f) => ContraMonoidal f where
contraunit :: f a
contrazip :: f a -> f b -> f (Either a b)
Haskopb <~ acontracurry :: (Either c b <~ a) -> (c <~ (b <~ a))contraapply :: b -> Either a (a <~ b)
Eğer hafıza bana hizmet ederse, buradaki engeller Haskell'e özgü değildir, daha çok 'Ha s kKartezyen kapalı olmak (her zamanki el sallamalarına kadar), en çok yazılan lambda calculi ile paylaştığı bir özelliktir, bu yüzden CoApplicativeçoğu ayarda çok uzaklara gitme olasılığınız yoktur .
Bununla birlikte, dualizasyon için daha misafirperver olan monoidal kapalı bir kategoride daha iyi şansınız olabilir. Özellikle, her ikisinin Kleisli (Cont r)ve zıt kategorisinin monoidal kapalı olduğuna inanıyorum , bu yüzden bu fikirleri keşfetmek için daha iyi bir bağlam olabilir.