आवेदकों रचना, भिक्षुओं नहीं है


110

आवेदकों रचना, भिक्षुओं नहीं है।

उपरोक्त कथन का क्या अर्थ है? और कब एक दूसरे के लिए बेहतर है?


5
आपको यह कथन कहां से मिला? कुछ संदर्भ देखने में मददगार हो सकते हैं।
फ़ूज

@FUZxxl: मैंने इसे कई अलग-अलग लोगों से बार-बार सुना है, हाल ही में ट्विटर पर देबाशीष से।
13 फरवरी को 12f11

3
@stephen tetley: ध्यान दें कि कई ऐसे Applicativeएस वास्तव में एस के पूरे परिवार हैं Monad, अर्थात् संरचना के प्रत्येक "आकार" के लिए एक। ZipListएक नहीं है Monad, लेकिन ZipListएक निश्चित लंबाई के हैं। Readerएक सुविधाजनक विशेष (या यह सामान्य है?) मामला जहां "संरचना" का आकार पर्यावरण के प्रकार की कार्डिनैलिटी के रूप में तय किया गया है।
सीए मैक्कैन

3
@CAMcCann उन सभी zippy ऐप्लिकेशंस (चाहे वे ट्रंकट या पैड) को मोनड्स तक सीमित रखते हैं यदि आप आकार को एक तरह से ठीक करते हैं जो Readerआइसोमॉर्फिज़्म तक एक मोनड तक है। एक बार जब आप एक कंटेनर के आकार को ठीक कर लेते हैं, तो यह मेमो ट्राई की तरह प्रभावी रूप से पदों से एक फ़ंक्शन को एनकोड करता है। पीटर हैनकॉक ऐसे फंक्शनलर्स को "नैपेरियन" कहते हैं, क्योंकि वे लॉगरिथम के नियमों का पालन करते हैं।
सुअर का बच्चा

4
@stephen tetley: अन्य उदाहरणों में निरंतर-मोनॉइड एपेरेटिव (जो कि मोनड्स की रचना है, लेकिन एक मोनड नहीं है), और यूनिट-डिलेड एप्लिकेटिव (जिसमें बेहतर रूप से शामिल नहीं हुआ था) शामिल हैं।
कबूतर

जवाबों:


115

यदि हम प्रकारों की तुलना करते हैं

(<*>) :: Applicative a => a (s -> t) -> a s -> a t
(>>=) :: Monad m =>       m s -> (s -> m t) -> m t

हमें दो अवधारणाओं को अलग करने का एक संकेत मिलता है। यह दर्शाता है कि (s -> m t)किस प्रकार के (>>=)मूल्य में sगणना का व्यवहार निर्धारित किया जा सकता है m t। मोनाड्स मूल्य और गणना परतों के बीच हस्तक्षेप की अनुमति देते हैं। (<*>)ऑपरेटर ऐसी कोई हस्तक्षेप की अनुमति देता है: समारोह और तर्क संगणना मूल्यों पर निर्भर नहीं है। यह वास्तव में काटता है। तुलना

miffy :: Monad m => m Bool -> m x -> m x -> m x
miffy mb mt mf = do
  b <- mb
  if b then mt else mf

जो दो संगणनाओं (जैसे प्रक्षेपास्त्रों को प्रक्षेपित करने और युद्धविराम पर हस्ताक्षर करने) के बीच निर्णय लेने के लिए कुछ प्रभाव के परिणाम का उपयोग करता है , जबकि

iffy :: Applicative a => a Bool -> a x -> a x -> a x
iffy ab at af = pure cond <*> ab <*> at <*> af where
  cond b t f = if b then t else f

जो दो संगणना के मूल्यों केab बीच चयन करने के लिए मूल्य का उपयोग करता है और दोनों को, शायद दुखद प्रभाव के लिए किया जाता है।ataf

मानादिक संस्करण (>>=)एक मूल्य से एक संगणना चुनने के लिए अतिरिक्त शक्ति पर अनिवार्य रूप से निर्भर करता है , और यह महत्वपूर्ण हो सकता है। हालाँकि, उस शक्ति का समर्थन करने से भिक्षुओं की रचना कठिन हो जाती है। अगर हम 'डबल-बाइंड' बनाने की कोशिश करते हैं

(>>>>==) :: (Monad m, Monad n) => m (n s) -> (s -> m (n t)) -> m (n t)
mns >>>>== f = mns >>-{-m-} \ ns -> let nmnt = ns >>= (return . f) in ???

हमें यह बहुत दूर लगता है, लेकिन अब हमारी परतें पूरी तरह से टूट चुकी हैं। हमारे पास एक है n (m (n t)), इसलिए हमें बाहरी से छुटकारा पाने की आवश्यकता है n। जैसा कि अलेक्जेंड्रे सी कहते हैं, हम कर सकते हैं कि अगर हमारे पास एक उपयुक्त है

swap :: n (m t) -> m (n t)

nअंदर की ओर और joinदूसरे को अनुमति देने के लिए n

कमजोर 'डबल-अप' को परिभाषित करना बहुत आसान है

(<<**>>) :: (Applicative a, Applicative b) => a (b (s -> t)) -> a (b s) -> a (b t)
abf <<**>> abs = pure (<*>) <*> abf <*> abs

क्योंकि परतों के बीच कोई हस्तक्षेप नहीं है।

इसके विपरीत, यह पहचानना अच्छा है जब आपको वास्तव में Monadएस की अतिरिक्त शक्ति की आवश्यकता होती है , और जब आप कठोर गणना संरचना का Applicativeसमर्थन कर सकते हैं।

ध्यान दें, वैसे, हालांकि मठों की रचना करना मुश्किल है, यह आपकी ज़रूरत से ज़्यादा हो सकता है। प्रकार -effects के m (n v)साथ कंप्यूटिंग को इंगित करता है m, फिर n-values ​​के साथ -value करने के लिए कंप्यूटिंग करता है v, जहां -effects प्रारंभ mहोने से पहले समाप्त हो जाता है n(इसलिए इसके लिए आवश्यकता है swap)। यदि आप m-effects के साथ बस इंटरलेवेव करना चाहते हैं n, तो रचना शायद पूछना बहुत ज्यादा है!


3
Iffy उदाहरण के लिए आप कहते हैं कि यह "ab के मूल्य का उपयोग दो संगणनाओं के मानों के बीच में और ऊपर, दोनों को करने के लिए करता है, शायद दुखद प्रभाव के लिए।" क्या हास्केल का आलसी स्वभाव इस से आपकी रक्षा नहीं करता है? अगर मेरे पास सूची है (\ btf -> यदि b फिर t और f): [] और फिर कथन को निष्पादित करें: सूची <*> शुद्ध सत्य <*> शुद्ध "नमस्ते" <*> शुद्ध (त्रुटि "बुरा")। ... मुझे "हैलो" मिलता है और त्रुटि कभी नहीं होती है। यह कोड लगभग एक मठ के रूप में सुरक्षित या नियंत्रित नहीं है, लेकिन पोस्ट ऐसा लगता है कि यह सुझाव दे रहा है कि आवेदक सख्त मूल्यांकन का कारण बनते हैं। हालांकि कुल मिलाकर शानदार पोस्ट! धन्यवाद!
shj

7
आप अभी भी दोनों के प्रभाव प्राप्त करते हैं , लेकिन शुद्ध (त्रुटि "खराब") कोई भी नहीं है। यदि, दूसरी ओर, आप iffy (शुद्ध ट्रू) (शुद्ध "हैलो") (त्रुटि "खराब") का प्रयास करते हैं, तो आपको एक त्रुटि मिलती है जो मिफ़ी से बच जाती है। इसके अलावा, यदि आप iffy (शुद्ध ट्रू) (शुद्ध 0) [1,2] जैसी कुछ कोशिश करते हैं, तो आपको [0] के बजाय [0,0] मिलेगा। आवेदकों में उनके बारे में एक प्रकार की सख्ती होती है, जिसमें वे गणनाओं के निश्चित अनुक्रमों का निर्माण करते हैं, लेकिन उन संगणनों से उत्पन्न मूल्य अभी भी संयुक्त रूप से आलसी हैं, जैसा कि आप देखते हैं।
सुअर का बच्चा

क्या यह सच है, कि किसी भी सन्यासी के लिए mऔर nआप हमेशा एक मोनाड ट्रांसफॉर्मर लिख सकते हैं mt, और n (m t)उपयोग में काम कर सकते हैं mt n t? तो आप हमेशा साधुओं की रचना कर सकते हैं, यह सिर्फ ट्रांसफॉर्मर का उपयोग करके अधिक जटिल है?
रॉन

4
इस तरह के ट्रांसफार्मर अक्सर मौजूद होते हैं, लेकिन जहां तक ​​मुझे पता है, उन्हें उत्पन्न करने का कोई विहित तरीका नहीं है। अलग-अलग मठों से interleaved प्रभावों को हल करने के बारे में अक्सर एक वास्तविक विकल्प होता है, क्लासिक उदाहरण अपवाद और राज्य। एक अपवाद रोल बैक में परिवर्तन होना चाहिए या नहीं? दोनों विकल्पों का अपना स्थान है। ऐसा कहने के बाद, एक "मुक्त मोनाड" चीज है जो "मनमाना इंटरलेइंग" व्यक्त करती है। data Free f x = Ret x | Do (f (Free f x)), तब data (:+:) f g x = Inl (f x) | Tnr (g x), और विचार करें Free (m :+: n)। इंटरलेयविंग्स को कैसे चलाना है, इसका चुनाव देरी करता है।
सुअर का बच्चा

@pigworker आलसी / सख्त बहस को लेकर। मुझे लगता है कि आवेदकों के साथ आप गणना के भीतर से प्रभाव को नियंत्रित नहीं कर सकते हैं , लेकिन प्रभाव-परत बहुत अच्छी तरह से बाद के मूल्यों का मूल्यांकन नहीं करने का निर्णय ले सकती है। (आवेदक) पार्सर्स के लिए इसका मतलब है कि यदि पार्सर जल्दी विफल हो जाता है, तो बाद के पार्सर का मूल्यांकन / इनपुट पर लागू नहीं किया जाता है। इसके लिए Maybeइसका मतलब है कि एक प्रारंभिक बाद के / बाद Nothingके मूल्यांकन को दबा देगा । क्या ये सही है? aJust a
जिग्गीस्टार

75

आवेदकों रचना, भिक्षुओं नहीं है।

मोनाड्स रचना करते हैं, लेकिन परिणाम एक सनक नहीं हो सकता है। इसके विपरीत, दो अनुप्रयोगों की संरचना जरूरी एक आवेदक है। मुझे मूल कथन के इरादे पर संदेह है कि "व्यावहारिकता रचना करती है, जबकि अद्वैतता नहीं।" रेफ़्रासेड, " Applicativeरचना के तहत बंद है, और Monadनहीं है।"


24
इसके अतिरिक्त, कोई भी दो अनुप्रयोग पूरी तरह से यांत्रिक तरीके से रचना करते हैं, जबकि दो संन्यासी की रचना द्वारा गठित मोनाड उस रचना के लिए विशिष्ट होता है।
Apocalisp

12
इसके अलावा अन्य तरीकों से मोनोड्स की रचना की जाती है, दो मोनड्स का उत्पाद एक मोनाड है, यह केवल प्रतिपादक हैं जिन्हें किसी प्रकार के वितरण कानून की आवश्यकता होती है।
एडवर्ड KMETT

@Apocalisp के साथ, टिप्पणी शामिल है, यह सबसे अच्छा और सबसे संक्षिप्त जवाब है।
पॉल ड्रेपर

39

यदि आपके पास आवेदक हैं A1और A2, तो वह प्रकार data A3 a = A3 (A1 (A2 a))भी आवेदक है (आप इस तरह के उदाहरण को सामान्य तरीके से लिख सकते हैं)।

दूसरी ओर, यदि आपके पास भिक्षु हैं M1और M2फिर प्रकार data M3 a = M3 (M1 (M2 a))जरूरी नहीं है कि एक भिक्षु है ( रचना के लिए >>=या उसके joinलिए कोई समझदार सामान्य कार्यान्वयन नहीं है )।

एक उदाहरण प्रकार हो सकता है [Int -> a](यहां हम एक प्रकार के रचनाकार के []साथ रचना करते हैं (->) Int, जिसमें दोनों मोनड हैं)। आप आसानी से लिख सकते हैं

app :: [Int -> (a -> b)] -> [Int -> a] -> [Int -> b]
app f x = (<*>) <$> f <*> x

और यह किसी भी आवेदन के लिए सामान्यीकृत करता है:

app :: (Applicative f, Applicative f1) => f (f1 (a -> b)) -> f (f1 a) -> f (f1 b)

लेकिन इसकी कोई समझदार परिभाषा नहीं है

join :: [Int -> [Int -> a]] -> [Int -> a]

यदि आप इसके प्रति असंबद्ध हैं, तो इस अभिव्यक्ति पर विचार करें:

join [\x -> replicate x (const ())]

लौटी हुई सूची की लंबाई को एक पूर्णांक प्रदान करने से पहले पत्थर में सेट किया जाना चाहिए, लेकिन इसकी सही लंबाई उस पूर्णांक पर निर्भर करती है जो प्रदान किया गया है। इस प्रकार, joinइस प्रकार के लिए कोई सही फ़ंक्शन मौजूद नहीं हो सकता है।


1
... तो भिक्षुओं से बचें जब कोई फ़ंक्शन करेगा?
andrew cooke

2
@andrew, अगर आपका मतलब functor है, तो हाँ, फंक्शंस सरल हैं और पर्याप्त होने पर उपयोग किया जाना चाहिए। ध्यान दें कि यह हमेशा नहीं है। उदाहरण के IOबिना, Monadप्रोग्राम के लिए बहुत मुश्किल होगा। :)
रास्टर

17

दुर्भाग्य से, हमारा वास्तविक लक्ष्य, भिक्षुओं की रचना, बल्कि अधिक कठिन है। .. वास्तव में, हम वास्तव में यह साबित कर सकते हैं कि, एक निश्चित अर्थ में, केवल दो मठों के संचालन का उपयोग करके उपरोक्त प्रकार के साथ एक सम्मिलित कार्य का निर्माण करने का कोई तरीका नहीं है (प्रमाण की रूपरेखा के लिए परिशिष्ट देखें)। यह इस प्रकार है कि जिस तरह से हम एक संरचना बनाने की उम्मीद कर सकते हैं, अगर दो घटकों को जोड़ने वाले कुछ अतिरिक्त निर्माण हैं।

कम्पोज़िंग मोनड्स, http://web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf


4
टीएल; डॉ। अधीर पाठकों के लिए: आप भिक्षुओं की रचना कर सकते हैं यदि (च?) आप एक प्राकृतिक परिवर्तन प्रदान कर सकते हैंswap : N M a -> M N a
एलेक्जेंडर सी।

@ अलेक्सांड्रे सी .: बस "अगर", मुझे संदेह है। सभी मंसर्ड ट्रांसफ़ॉर्मर्स को प्रत्यक्ष फ़ंक्शनल रचना द्वारा वर्णित नहीं किया गया है। उदाहरण के लिए, ContT r m aन तो है , और न m (Cont r a)ही मोटे तौर पर है । Cont r (m a)StateT s m aReader s (m (Writer s a))
सीए मैक्कैन

@ मैक मैकन: मैं (एम मोनड, एन मोनड, एमएन मोनड, एनएम मोनड) से प्राप्त नहीं कर सकता (वहाँ स्वैप मौजूद है: एमएन -> एनएम प्राकृतिक)। तो चलो अब के लिए "अगर" से चिपके रहते हैं (शायद जवाब कागज में है, मुझे कबूल करना चाहिए कि मैंने इसे जल्दी देखा)
एलेक्जेंडर सी।

1
@ अलेक्सांड्रे सी।: यह निर्दिष्ट करते हुए कि रचनाएँ भिक्षु हैं, वैसे भी पर्याप्त नहीं हो सकती हैं - आपको संपूर्ण के साथ दो भागों को संबंधित करने के लिए भी किसी तरह की आवश्यकता होती है। के अस्तित्व swapकि रचना दो "सहयोग" किसी भी तरह की सुविधा देता है निकलता है। इसके अलावा, ध्यान दें कि sequenceकुछ साधुओं के लिए "स्वैप" का एक विशेष मामला है। तो flipवास्तव में है।
सीए मैककैन

7
यह लिखने के swap :: N (M x) -> M (N x)लिए मुझे लगता है कि आप returns(उपयुक्त रूप से fmapपैड) का उपयोग कर सकते हैं Mसामने और Nपीछे एक डालने के लिए , से जा रहा है N (M x) -> M (N (M (N x))), तो joinअपने पाने के लिए समग्र का उपयोग करें M (N x)
सूअर का बच्चा

7

वितरण कानून समाधान l: MN -> NM पर्याप्त है

एनएम की शुद्धता की गारंटी करने के लिए। इसे देखने के लिए आपको एक इकाई और एक बहु की आवश्यकता होती है। मैं बहु पर ध्यान केंद्रित करूँगा (इकाई इकाई है-_NMM)

NMNM - l -> NNMM - mult_N mult_M -> NM

ऐसा नहीं होता है गारंटी देता है कि एमएन एक सनद है।

हालाँकि, महत्वपूर्ण अवलोकन तब चलता है जब आपके पास वितरण कानून के समाधान होते हैं

l1 : ML -> LM
l2 : NL -> LN
l3 : NM -> MN

इस प्रकार, LM, LN और MN मोनड हैं। यह सवाल उठता है कि क्या LMN एक सन्यासी (या तो) है

(एमएन) एल -> एल (एमएन) या एन (एलएम) द्वारा -> (एलएम) एन

हमारे पास इन मानचित्रों को बनाने के लिए पर्याप्त संरचना है। हालांकि, जैसा कि यूजेनिया चेंग देखता है , हमें निर्माण की एकरूपता की गारंटी के लिए एक हेक्सागोनल स्थिति (यांग-बैक्सटर समीकरण की प्रस्तुति के लिए राशि) की आवश्यकता है। वास्तव में, हेक्सागोनल स्थिति के साथ, दो अलग-अलग मठों का संयोग होता है।


9
यह शायद एक महान जवाब है, लेकिन यह चला गया हूँश मेरे सिर पर जिस तरह से।
डैन बर्टन

1
ऐसा इसलिए है, क्योंकि एप्लिकेटिव और हैस्केल शब्द का उपयोग करते हुए, यह हैस्केल के बारे में एक प्रश्न है, लेकिन एक अलग संकेतन में एक उत्तर के साथ।
कोडेशॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.