Arrows
श्रेणियों द्वारा सामान्यीकृत किया जाता है, और Category
टाइपक्लास द्वारा।
class Category f where
(.) :: f a b -> f b c -> f a c
id :: f a a
Arrow
typeclass परिभाषा Category
एक सुपर क्लास के रूप में है। श्रेणियां (हैकेल भावना में) कार्यों को सामान्यीकृत करें (आप उन्हें लिख सकते हैं लेकिन उन्हें लागू नहीं कर सकते हैं) और इसलिए निश्चित रूप से "गणना का मॉडल" है। Arrow
tuples के साथ काम करने के लिए अतिरिक्त संरचना के साथ Category
प्रदान करता है। इसलिए, Category
हास्केल की फ़ंक्शन स्पेस के बारे में कुछ दर्पण करता है, Arrow
उत्पाद प्रकारों के बारे में कुछ बताता है।
प्रत्येक Monad
"क्लेस्ली श्रेणी" नामक किसी चीज़ को जन्म देता है और यह निर्माण आपको ArrowApply
के उदाहरण देता है। आप किसी भी ArrowApply
से बाहर बना सकते हैं जैसे कि पूर्ण सर्कल जा रहा है, आपका व्यवहार नहीं बदलता है, इसलिए कुछ गहरी समझ में Monad
और ArrowApply
समान हैं।
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)
instance Monad m => Arrow (Kleisli m) where
arr f = Kleisli (return . f)
first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
असल में हर Arrow
एक Applicative
Category
सुपर क्लास के अलावा (सार्वभौमिक प्रकार सही पाने के लिए मात्रा निर्धारित) को जन्म देता है, और मेरा मानना है कि उचित Category
और Applicative
के संयोजन अपने Arrow
को फिर से संगठित करने के लिए पर्याप्त है।
तो, ये संरचनाएं गहराई से जुड़ी हुई हैं।
चेतावनी: की इच्छा-धोनी टिप्पणी। सोच के Functor
/Applicative
/Monad
तरह से और सोच के Category
/Arrow
रास्ता के बीच एक केंद्रीय अंतर यह है कि जबकि Functor
और उसके जैसे लोग वस्तु (हास्केल में प्रकार) के स्तर पर सामान्यीकरण, कर रहे हैं Category
/Arrow
की generelazation हैं morphism (हास्केल में कार्य) की धारणा। मेरा विश्वास यह है कि सामान्यीकृत morphism के स्तर पर सोच सामान्यीकृत ऑब्जेक्ट्स के स्तर पर सोचने से उच्च स्तर का अबास्ट्रक्शन शामिल है। कभी-कभी यह अच्छी बात है, दूसरी बार यह नहीं है। दूसरी ओर, इस तथ्य के बावजूद कि Arrows
का एक विशिष्ट आधार है, और गणित में कोई भी Applicative
दिलचस्प नहीं लगता है, यह मेरी समझ है कि Applicative
आमतौर पर Arrow
से बेहतर समझा जाता है।
असल में आप सोच सकते हैं "श्रेणी < तीर < ArrowApply" और "functor < अनुप्रयोगी < इकाई" ऐसी है कि "श्रेणी ~ functor", "तीर ~ अनुप्रयोगी" और "ArrowApply ~ इकाई"।
अधिक नीचे कंक्रीट: एक बार "तीर" की दिशा पलट सकता है "दोहरे" या "सह-निर्माण पाने के लिए स्पष्ट निर्माण में (सिर्फ यहाँ morphisms अर्थ): अन्य संरचनाओं अभिकलन मॉडल करने के लिए के रूप में "। तो, अगर एक इकाई
class Functor m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
के रूप में परिभाषित किया गया है (ठीक है, मुझे पता है कि कैसे हास्केल चीजों को परिभाषित करता है नहीं है, लेकिन ma >>= f = join $ fmap f ma
और join x = x >>= id
तो यह बस के रूप में अच्छी तरह से हो सकता है) तो comonad
class Functor m => Comonad m where
extract :: m a -> a -- this is co-return
duplicate :: m a -> m (m a) -- this is co-join
है
यह बात भी काफी आम है। यह पता चला है कि Comonad
सेलुलर ऑटोमाटा की बुनियादी अंतर्निहित संरचना है। completness के लिए, मैं कहना चाहिए कि एडवर्ड Kmett के Control.Comonad
पुट duplicate
functor और Comonad
"बढ़ाई functors के लिए" के बीच एक कक्षा में है क्योंकि आप भी परिभाषित कर सकते हैं
extend :: (m a -> b) -> m a -> m b -- Looks familiar? this is just the dual of >>=
extend f = fmap f . duplicate
--this is enough
duplicate = extend id
ऐसा लगता है कि सब Monad
रों भी "बढ़ाई"
हैं
monadDuplicate :: Monad m => m a -> m (m a)
monadDuplicate = return
जबकि सभी Comonads
"joinable" हैं
comonadJoin :: Comonad m => m (m a) -> m a
comonadJoin = extract
तो
ये संरचनाएं एक साथ बहुत करीब हैं।
मोनाड बनाम तीर पेज एक ऐसे पेपर से लिंक करता है जो आवेदक फैनक्टर (उर्फ मुहावरे) की तुलना करता है। –
आवेदक फंक्शंस सबसे निश्चित रूप से * composable गणना पर अच्छा * हैं! वास्तव में, वे मोनैड्स से बेहतर लिखते हैं (दो आवेदक फंक्शंस की संरचना एक आवेदक मज़ेदार है, जो मोनैड के लिए नहीं है)। – ehird