हास्केल: <*> का उच्चारण कैसे किया जाता है? [बन्द है]


109

आप इन कार्यों को कैसे करें

(<*>) :: f (a -> b) -> f a -> f b
(*>)  :: f a -> f b -> f b
(<*)  :: f a -> f b -> f a

(यही है, अगर वे ऑपरेटर नहीं थे, तो उन्हें क्या कहा जा सकता है?)

एक साइड नोट के रूप में, यदि आप pureगैर-गणितज्ञों के अधिक अनुकूल कुछ का नाम बदल सकते हैं, तो आप इसे क्या कहेंगे?


6
@ जे कूपर ... क्या आप सुन पाएंगे कि हम इसका उच्चारण कैसे करते हैं? :) आप एक वॉयस रिकॉर्डिंग और प्लेबैक सुविधा के लिए meta.stackoverflow.com पर एक अनुरोध पोस्ट करना चाह सकते हैं :)।
किरिल

8
यह स्पष्ट है "अच्छा दु: ख, वे वास्तव में ऑपरेटरों से बाहर चल रहे थे, वे नहीं थे?" इसके अलावा, एक अच्छा नाम pureहो सकता है makeApplicative
चक

@Lirik, ठीक है, मुझे लगता है कि उच्चारण से मेरा मतलब है "whaddya इस बात को बुलाओ" :) @Chuck, अपने pureसुझाव को एक उत्तर के रूप में पोस्ट करें और मैं आपको उत्साहित करूंगा
J Cooper

6
(<*>) Control.Applicative संस्करण Control.Monad का "एपी" है, इसलिए "एपी" शायद सबसे उपयुक्त नाम है।
एडवर्ड KMETT

11
मैं इसे एक चक्रवात कहूँगा, लेकिन यह सिर्फ मुझे है।
RCIX

जवाबों:


245

क्षमा करें, मैं वास्तव में अपने गणित को नहीं जानता हूं, इसलिए मैं उत्सुक हूं कि एप्लास्टिक टाइपकास्ट में कार्यों का उच्चारण कैसे किया जाए

मुझे लगता है कि आपके गणित को जानना, काफी हद तक अप्रासंगिक है। जैसा कि आप शायद जानते हैं, हास्केल सार गणित के विभिन्न क्षेत्रों से शब्दावली के कुछ बिट्स उधार लेते हैं, विशेष रूप से श्रेणी सिद्धांत , जहां से हमें फंक्शनलर्स और मोनाड्स मिलते हैं। हास्केल में इन शब्दों का उपयोग कुछ हद तक औपचारिक गणितीय परिभाषाओं से भिन्न होता है, लेकिन वे आमतौर पर पर्याप्त रूप से अच्छे वर्णनात्मक शब्द हो सकते हैं।

Applicativeप्रकार वर्ग के बीच में कहीं बैठता है Functorऔर Monad, इसलिए एक यह एक ऐसी ही गणितीय आधार है की उम्मीद करेंगे। Control.Applicativeमॉड्यूल के लिए प्रलेखन के साथ शुरू होता है:

यह मॉड्यूल एक फ़न्क्टर और एक सनक के बीच एक संरचना मध्यवर्ती का वर्णन करता है: यह शुद्ध अभिव्यक्ति और अनुक्रमण प्रदान करता है, लेकिन कोई बंधन नहीं। (तकनीकी रूप से, एक मजबूत लक्ष्मण मोनोएडल फंक्टर है।)

हम्म।

class (Functor f) => StrongLaxMonoidalFunctor f where
    . . .

Monadमुझे लगता है कि काफी आकर्षक नहीं है।

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


अगर हम (<*>)यह जानना चाहते हैं कि इसे क्या कहा जाए तो यह जानने में मदद मिल सकती है कि इसका मूल अर्थ क्या है।

तो क्या साथ हो रहा है Applicativeवैसे भी, और क्यों करते हैं हम यह है कि कहते हैं?

Applicativeव्यवहार में कितनी मात्रा में मनमाना कार्यों को उठाने का एक तरीका है Functor। के संयोजन पर विचार करें Maybe(यकीनन सबसे सरल गैर-तुच्छ Functor) और Bool(इसी तरह सबसे सरल गैर-तुच्छ डेटा प्रकार)।

maybeNot :: Maybe Bool -> Maybe Bool
maybeNot = fmap not

फंक्शन fmapहमें notकाम करने से Boolलेकर काम करने तक की सुविधा देता है Maybe Bool। लेकिन अगर हम उठाना चाहते हैं तो क्या होगा (&&)?

maybeAnd' :: Maybe Bool -> Maybe (Bool -> Bool)
maybeAnd' = fmap (&&)

ठीक है, यह वही नहीं है जो हम चाहते हैं ! वास्तव में, यह बहुत बेकार है। हम चतुर होने की कोशिश कर सकते हैं और पीछे से दूसरे Boolमें घुस सकते हैं Maybe...

maybeAnd'' :: Maybe Bool -> Bool -> Maybe Bool
maybeAnd'' x y = fmap ($ y) (fmap (&&) x)

... लेकिन यह अच्छा नहीं है। एक बात के लिए, यह गलत है। एक और बात के लिए, यह बदसूरत है । हम कोशिश कर सकते हैं, लेकिन यह पता चलता है कि मनमाने ढंग से काम करने के लिए कई तर्कों के एक समारोह को उठानेFunctor का कोई तरीका नहीं है । कष्टप्रद!

दूसरी ओर, हम इसे आसानी से कर सकता है अगर हम इस्तेमाल किया Maybeहै Monadउदाहरण:

maybeAnd :: Maybe Bool -> Maybe Bool -> Maybe Bool
maybeAnd x y = do x' <- x
                  y' <- y
                  return (x' && y')

जिसके कारण - अब, यह परेशानी का एक बहुत बस एक साधारण समारोह का अनुवाद करने में है Control.Monad, यह स्वतः ही करने के लिए एक समारोह प्रदान करता है liftM2। इसके नाम में 2 इस तथ्य को संदर्भित करता है कि यह ठीक दो तर्कों के कार्यों पर काम करता है; समान कार्य 3, 4 और 5 तर्क कार्यों के लिए मौजूद हैं। ये कार्य बेहतर हैं , लेकिन सही नहीं हैं, और तर्कों की संख्या बदसूरत और अनाड़ी है।

जो हमें उस पेपर पर लाता है जिसने एप्लिकेशन टाइप क्लास की शुरुआत की थी । इसमें, लेखक अनिवार्य रूप से दो अवलोकन करते हैं:

  • बहु-तर्क कार्यों को उठाना Functorएक बहुत ही स्वाभाविक बात है
  • ऐसा करने से पूर्ण क्षमताओं की आवश्यकता नहीं होती है Monad

सामान्य फ़ंक्शन एप्लिकेशन को सरल शब्दों के शब्दों में लिखा जाता है, इसलिए "उठा हुआ आवेदन" को जितना संभव हो उतना सरल और प्राकृतिक बनाने के लिए, पेपर infix ऑपरेटरों को आवेदन के लिए खड़े होने के लिएFunctor परिचय देता है , और इसे टाइप करने के लिए जो आवश्यक है, प्रदान करने के लिए एक प्रकार वर्ग। ।

जिनमें से सभी हमें निम्न बिंदु पर लाते हैं: (<*>)बस फ़ंक्शन अनुप्रयोग का प्रतिनिधित्व करता है - इसलिए आप इसे व्हाट्सएप "जूसकैप्सिशन ऑपरेटर" की तुलना में किसी भी अलग उच्चारण क्यों करते हैं?

लेकिन अगर यह बहुत संतोषजनक नहीं है, तो हम देख सकते हैं कि Control.Monadमॉड्यूल एक फ़ंक्शन भी प्रदान करता है जो मोनड्स के लिए एक ही काम करता है:

ap :: (Monad m) => m (a -> b) -> m a -> m b

कहाँ ap"लागू" का संक्षिप्त रूप ज़ाहिर है, है। चूंकि कोई भी Monadहो सकता है Applicative, और apबाद में मौजूद सुविधाओं के केवल सबसेट की जरूरत होती है, हम शायद यह कह सकते हैं कि यदि (<*>)कोई ऑपरेटर नहीं था, तो उसे बुलाया जाना चाहिए ap


हम दूसरी दिशा से भी चीजों को देख सकते हैं। Functorउठाने आपरेशन कहा जाता है fmap, क्योंकि यह का सामान्यीकरण है mapसूचियों पर आपरेशन। सूचियों पर किस तरह का फ़ंक्शन काम करेगा (<*>)? वहाँ apसूचियों पर क्या है, ज़ाहिर है, लेकिन यह अपने आप में विशेष रूप से उपयोगी नहीं है।

वास्तव में, सूचियों के लिए शायद अधिक प्राकृतिक व्याख्या है। निम्न प्रकार के हस्ताक्षर को देखते समय आपके मन में क्या आता है?

listApply :: [a -> b] -> [a] -> [b]

वहाँ कुछ तो बस सूची में अस्तर के विचार के बारे में आकर्षक है, दूसरे के पहले तत्व में प्रत्येक फ़ंक्शन को लागू करना। दुर्भाग्य से हमारे पुराने दोस्त के लिए Monad, यह सरल ऑपरेशन मोनड कानूनों का उल्लंघन करता है यदि सूचियां अलग-अलग लंबाई की हैं। लेकिन यह एक ठीक है Applicative, जिस स्थिति में एक सामान्यीकृत संस्करण को एक साथ स्ट्रिंग(<*>) करने का एक तरीका बन जाता है , तो शायद हम इसे कॉल करने की कल्पना कर सकते हैं ?zipWithfzipWith


यह ज़िपिंग विचार वास्तव में हमें पूर्ण चक्र लाता है। उस गणित की सामग्री को पहले याद करें, मोनोएडल फंक्शनलर्स के बारे में? जैसा कि नाम से ही पता चलता है, ये मोनॉयड और फंक्शनलर्स की संरचना के संयोजन का एक तरीका है, जो दोनों परिचित हास्केल प्रकार वर्ग हैं:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class Monoid a where
    mempty :: a
    mappend :: a -> a -> a

यदि आप उन्हें एक साथ एक बॉक्स में रखते हैं और इसे थोड़ा ऊपर हिलाते हैं तो ये कैसा दिखेगा? से Functorहम एक के विचार रखेंगे अपने प्रकार पैरामीटर की संरचना स्वतंत्र से, और Monoidहम कार्यों के समग्र रूप रखेंगे:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ?
    mfAppend :: f ? -> f ? -> f ?

हम यह नहीं मानना ​​चाहते हैं कि वास्तव में "खाली" बनाने का एक तरीका है Functor, और हम एक मनमाने प्रकार के मूल्य को जोड़ नहीं सकते हैं, इसलिए हम इसके प्रकार को ठीक mfEmptyकरेंगे f ()

हम भी mfAppendएक निरंतर प्रकार के पैरामीटर की आवश्यकता के लिए बाध्य नहीं करना चाहते हैं , इसलिए अब हमारे पास यह है:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ()
    mfAppend :: f a -> f b -> f ?

परिणाम प्रकार किसके लिए है mfAppend? हमारे पास दो मनमाने प्रकार हैं जिनके बारे में हमें कुछ नहीं पता है, इसलिए हमारे पास कई विकल्प नहीं हैं। सबसे समझदार बात दोनों को रखना है:

class (Functor f) => MonoidalFunctor f where
    mfEmpty :: f ()
    mfAppend :: f a -> f b -> f (a, b)

जिस बिंदु mfAppendपर अब स्पष्ट रूप से zipसूचियों का एक सामान्यीकृत संस्करण है , और हम Applicativeआसानी से पुनर्निर्माण कर सकते हैं:

mfPure x = fmap (\() -> x) mfEmpty
mfApply f x = fmap (\(f, x) -> f x) (mfAppend f x)

यह हमें दिखाता है कि pureकिसी के पहचान तत्व से संबंधित है Monoid, इसलिए इसके लिए अन्य अच्छे नाम एक इकाई मूल्य, एक अशक्त ऑपरेशन, या ऐसा कुछ भी सुझा सकते हैं।


यह लंबा था, इसलिए संक्षेप में:

  • (<*>) केवल एक संशोधित फ़ंक्शन अनुप्रयोग है, इसलिए आप इसे या तो "एपी" या "लागू करें" के रूप में पढ़ सकते हैं, या इसे पूरी तरह से उसी तरह से लागू कर सकते हैं जिस तरह से आप फ़ंक्शन को सामान्य करेंगे।
  • (<*>)zipWithसूचियों पर भी मोटे तौर पर सामान्यीकरण किया जाता है, इसलिए आप इसे "ज़िप फंपर के साथ" के रूप में पढ़ सकते हैं, इसी तरह fmap"मैप विथ ए फक्टर" के रूप में पढ़ने के लिए ।

पहला Applicativeप्रकार वर्ग के इरादे के करीब है - जैसा कि नाम से पता चलता है - इसलिए यही मैं सुझाता हूं।

वास्तव में, मैं उदारवादी उपयोग और गैर-उच्चारण को प्रोत्साहित करता हूं , जो सभी उठाए गए आवेदन ऑपरेटरों के हैं :

  • (<$>), जो एकल-तर्क कार्य को एक में बदल देता है Functor
  • (<*>), जो एक बहु-तर्क फ़ंक्शन के माध्यम से श्रृंखला बनाते हैं Applicative
  • (=<<), जो Monadएक मौजूदा संगणना पर प्रवेश करने वाले फ़ंक्शन को बांधता है

सभी तीनों, दिल से, बस नियमित रूप से काम करने वाले अनुप्रयोग हैं, थोड़ा सा मसालेदार।


6
@ कोलिन कोचेन: क्या आप सुनिश्चित हैं कि आपने "लंबे समय से प्रसारित" नहीं किया था? :) लेकिन हे, मैं इसे ले जाऊँगा! मैं हमेशा महसूस करता हूं कि Applicativeयह जिस कार्यात्मक शैली के लिए उपयुक्त है, उसे पर्याप्त प्यार नहीं मिलता है, इसलिए मैं इसके गुणों को थोड़ा विस्तार करने का मौका नहीं दे सकता, क्योंकि मैं यह समझाता हूं कि मैं (कैसे) उच्चारण नहीं करता (<*>)
सीए मैक्कैन

+1! कृपया इसी तरह से घना होने के लिए स्वतंत्र लग रहा है stackoverflow.com/questions/2104446/...
ग्रेग बेकन

6
क्या हास्केल के पास सिंटेक्स चीनी थी Applicative! कुछ ऐसा [| f a b c d |](जैसा मूल पेपर द्वारा सुझाया गया है)। फिर हमें <*>कॉम्बिनेटर की आवश्यकता नहीं होगी और आप इस तरह के एक्सप्रेशन को "फंक्शनल रिफरेंस में फंक्शन एप्लिकेशन" के उदाहरण के रूप में संदर्भित करेंगे
टॉम

1
@FredOverflow: नहीं, मेरा मतलब था Monad। या Functorया Monoidकुछ और जिसमें तीन विशेषणों से कम एक अच्छी तरह से स्थापित शब्द है। "प्रयोजनीय" केवल एक उदासीनता है, इसके बावजूद यथोचित वर्णनात्मक, नाम किसी ऐसी चीज पर थप्पड़ मारा जाता है, जिसकी आवश्यकता होती है।
सीए मैक्कैन

1
@pelotom: देखें [ stackoverflow.com/questions/12014524/…। जहाँ पर तरह-तरह के लोगों ने मुझे उस नोटेशन को प्राप्त करने के दो तरीके दिखाए।
एंड्रयूज

21

चूंकि मेरे पास CA मैककैन के तकनीकी उत्तर में सुधार करने की कोई महत्वाकांक्षा नहीं है , इसलिए मैं अधिक शराबी हूं:

यदि आप pureमेरे जैसे पॉडकॉन के लिए कुछ और अनुकूल नाम बदल सकते हैं , तो आप इसे क्या कहेंगे?

एक विकल्प के रूप में, विशेष रूप से चूंकि निरंतर गुस्से में और विश्वासघात से भरे हुए Monadसंस्करण के खिलाफ कोई रोना नहीं है , जिसे " return" कहा जाता है , मैं एक और नाम प्रस्तावित करता हूं, जो इसके कार्य को इस तरह से सुझाता है कि यह अतिरंजित नागरिकों को संतुष्ट कर सके। , और सबसे कार्यात्मक ... ठीक है, उम्मीद है, हर कोई इसके बारे में शिकायत कर सकता है inject:।

मान लो। में "सुई" यह Functor, Applicative, Monad, या क्या-है-आप। मैं " inject" के लिए मतदान करता हूं , और मैंने इस संदेश को मंजूरी दे दी।


4
मैं आमतौर पर "यूनिट" या "लिफ्ट" जैसी किसी चीज की ओर झुकता हूं, लेकिन उन लोगों के पास पहले से ही हास्केल में बहुत अधिक अर्थ हैं। injectएक उत्कृष्ट नाम है और शायद मेरी तुलना में बेहतर है, हालांकि एक मामूली साइड नोट के रूप में, "इंजेक्ट" का उपयोग किया जाता है - मुझे लगता है - स्मॉलटॉक और रूबी कुछ प्रकार के बाएं-गुना विधि के लिए। मैं नाम के उस विकल्प को कभी नहीं समझ पाया, हालांकि ...
सीए मैककैन

3
यह एक बहुत पुराना धागा है, लेकिन मुझे लगता है कि injectरूबी और स्मालटाक में उपयोग किया जाता है क्योंकि यह ऐसा है जैसे आप सूची में प्रत्येक तत्व के बीच एक ऑपरेटर को "इंजेक्ट" कर रहे हैं। कम से कम, कि कैसे मैं हमेशा इसके बारे में सोचा था।
जोनाथन स्टर्लिंग

1
उस पुराने साइड-थ्रेड को फिर से लेने के लिए : आप ऑपरेटरों को इंजेक्ट नहीं कर रहे हैं, आप पहले से ही मौजूद कंस्ट्रक्टरों को हटा रहे हैं (नष्ट कर रहे हैं)। (दूसरे तरीके से देखा गया, आप पुराने डेटा को एक नए प्रकार में इंजेक्ट कर रहे हैं ।) सूचियों के लिए, उन्मूलन बस है foldr। (आप की जगह (:)और []जहां, (:)2 आर्ग लेता है और []एक स्थिर है, इसलिए foldr (+) 0 (1:2:3:[])1+2+3+0।) पर Boolयह सिर्फ है if- then- else(दो स्थिरांक, एक चुनना) और के लिए Maybeयह कहा जाता है maybe... हास्केल इस के लिए कोई एक नाम / समारोह है, के रूप में सभी विभिन्न प्रकार है (सामान्य योग में सिर्फ पुनरावृत्ति / प्रेरण है)
कोई नहीं

@CAMcCann Smalltalk को वियतनाम युद्ध के मसौदे के बारे में एक Arlo Guthrie गीत से वह नाम मिला , जिसमें दुर्भाग्यशाली युवकों को एकत्र किया गया था, चयनित किया गया था, कभी-कभी अस्वीकार कर दिया जाता था, और अन्यथा इंजेक्शन लगाया जाता था।
टॉम एंडरसन

7

संक्षेप में:

  • <*>आप इसे लागू कर सकते हैं । तो Maybe f <*> Maybe aउच्चारित किया जा सकता के रूप में लागू Maybe fअधिकMaybe a

  • आप का नाम बदलने सकता है pureकरने के लिए of, कई JavaScript लाइब्रेरी करते हैं। जेएस में आप एक के Maybeसाथ बना सकते हैं Maybe.of(a)

साथ ही, हास्केल के विकी का भाषा ऑपरेटरों के उच्चारण पर एक पृष्ठ है


3
(<*>) -- Tie Fighter
(*>)  -- Right Tie
(<*)  -- Left Tie
pure  -- also called "return"

स्रोत: क्रिस एलन और जूली मोरोनुकी द्वारा पहले सिद्धांतों से हास्केल प्रोग्रामिंग


वे नाम बिल्कुल नहीं पकड़े गए हैं, जहां तक ​​मैं बता सकता हूं।
dfeuer

@dfeuer Haskellers की अगली पीढ़ी की प्रतीक्षा करते हैं जो उस किताब को अपनी प्राथमिक शिक्षण सामग्री के रूप में उपयोग कर रहे हैं।
dmvianna

1
यह हो सकता है। नाम भयानक हैं, हालांकि, क्योंकि उनका अर्थ से कोई संबंध नहीं है।
dfeuer

1
@dfeuer, मुझे कहीं भी एक अच्छा समाधान दिखाई नहीं देता है। "एपी" / "लागू करें" "टाई फाइटर" के रूप में अस्पष्ट है। सब कुछ फ़ंक्शन अनुप्रयोग है। हालांकि, नीले रंग से निकलने वाला एक नाम उपयोग के माध्यम से अर्थ प्राप्त कर सकता है। "Apple" एक अच्छा उदाहरण है। वैसे, इकाई वापसी है अनुप्रयोगी शुद्ध। यहां कोई आविष्कार नहीं हुआ।
दिनमान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.