2011-12-19 18 views
29

क्या हस्ताक्षर :: (Monad m) => m a -> a के साथ एक अंतर्निहित फ़ंक्शन है?मोनैडिक एक्शन से मूल्य निकालने के लिए कैसे करें

होगल बताता है कि ऐसा कोई कार्य नहीं है।

क्या आप समझा सकते हैं क्यों?

+2

संबंधित: [एक मोनड से मूल्य निकालना? Haskell] (http: // stackoverflow।कॉम/प्रश्न/7314789/ले-आउट-ए-वैल्यू-आउट-ऑफ-ए-मोनैड-हैकेल) – Jan

+14

ऐसा नहीं है, लेकिन एक ऐसा कार्य है जो 'ए' की उम्मीद वाले कार्यों में 'ए' की अपेक्षा करता है। : '(= <<) :: मोनाड एम => (ए -> एमबी) -> (एमए>> एमबी)'। अपनी अपेक्षाओं को उलटा करें, और आप ठीक होंगे। =) –

+3

वैनियल वाग्नेर ने जो कहा, उसी तरह से, लिफ्टएम :: मोनाड एम => (ए -> बी) -> (एमए>> एमबी) '> "नियमित" फ़ंक्शन इनपुट के रूप में एक मोनाडिक मान को स्वीकार करने की अनुमति देता है, लेकिन बदले में इसे "नियमित" मूल्य के बजाय एक monadic मूल्य आउटपुट करना होगा। –

उत्तर

41

एक इकाई केवल दो कार्यों की आपूर्ति:

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

इन दोनों प्रकार m a के बारे में कुछ वापसी, इसलिए वहाँ किसी भी तरह से प्रकार Monad m => m a -> a के एक समारोह प्राप्त करने के लिए इन गठबंधन करने के लिए कोई रास्ता नहीं है। ऐसा करने के लिए, आपको इन दो कार्यों से अधिक की आवश्यकता होगी, इसलिए आपको m के बारे में अधिक जानने की आवश्यकता है, यह एक मोनड है।

उदाहरण के लिए, Identity मोनड में runIdentity :: Identity a -> a है, और कई मोनैड के समान कार्य हैं, लेकिन इसे सामान्य रूप से प्रदान करने का कोई तरीका नहीं है। वास्तव में, मोनैड से "भागने" की अक्षमता IO जैसे मोनैड के लिए आवश्यक है।

5

क्योंकि यह कोई समझ नहीं सकता है (वास्तव में, कई उदाहरणों में कोई समझ नहीं आता है)।

उदाहरण के लिए, मैं इस तरह एक पार्सर इकाई से परिभाषित करें:

data Parser a = Parser (String ->[(a, String)]) 

अब वहाँ बिल्कुल कोई समझदार डिफ़ॉल्ट तरीका एक String एक Parser String से बाहर निकलना है। असल में, मोनाड के साथ इस से बाहर निकलने का कोई तरीका नहीं है। कुछ नहीं से कुछ हो रही

data Null a = Null 

instance Monad Null where 
    return a = Null 
    ma >>= f = Null 

अब (Monad m) => m a -> a मतलब है Null a -> a, अर्थात्:

21

वहाँ शायद इस तुलना में एक बेहतर जवाब है, लेकिन एक तरह से देखने के लिए कारण है कि आप एक प्रकार (Monad m) => m a -> a नहीं हो सकता एक अशक्त इकाई पर विचार करना है । आप ऐसा नहीं कर सकते

+4

दूसरी तरफ यह तथ्य अस्तित्व से 'जस्ट' को नहीं रोकता है। यह 'जस्ट' की सामग्री देता है और' कुछ भी नहीं 'के मामले में अपवाद उठाता है। आपका 'नल' मोनड हमेशा इस तरह के काल्पनिक मोनैड अनैपिंग फ़ंक्शन को कॉल करने पर अपवाद उठा सकता है। – Jan

+13

@ जेन: दूसरी तरफ जो या तो एक अच्छा विचार नहीं करता है। 'से जस्ट' भयानक है और बेहतर नहीं होगा। –

+1

@ सीए.एमसीकैन मैं आपकी टिप्पणी को आंशिक रूप से +1 करता हूं क्योंकि 'से ज़स्ट' खराब है ... लेकिन मुख्य रूप से क्योंकि आपने "अन्य हाथ" का उपयोग किया था। –

12

यह अस्तित्व में नहीं है क्योंकि Monad संरचना के लिए एक पैटर्न है, अपघटन के लिए एक पैटर्न नहीं है। आप इसे परिभाषित इंटरफ़ेस के साथ हमेशा एक साथ अधिक टुकड़े डाल सकते हैं। यह कुछ भी अलग करने के बारे में कुछ नहीं कहता है।

पूछना कि आप कुछ क्यों नहीं ले सकते हैं यह पूछने की तरह है कि क्यों जावा के Iterator इंटरफ़ेस में तत्वों को जोड़ने के लिए एक विधि शामिल नहीं है। यह सिर्फ Iterator इंटरफ़ेस के लिए नहीं है।

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

और fromJust की उपस्थिति उतनी ही अप्रासंगिक है। यह व्यवहार का हिस्सा नहीं है Monad का वर्णन करने का इरादा है। अन्य ने कई प्रकार के उदाहरण दिए हैं जहां काम करने के लिए extract के लिए कोई मूल्य नहीं है। लेकिन वे प्रकार अभी भी Monad के इच्छित अर्थशास्त्र का समर्थन करते हैं। यह महत्वपूर्ण है। इसका मतलब है कि Monad एक अधिक सामान्य इंटरफ़ेस है जिसके लिए आप इसे श्रेय दे रहे हैं।

6

हस्ताक्षर :: (Monad m) => m a -> a हस्ताक्षर के साथ एक बिल्ड-इन फ़ंक्शन है?

यदि होगल कहता है कि वहां नहीं है ... तो संभवत: ऐसा नहीं है कि "अंतर्निहित" की परिभाषा "आधार पुस्तकालयों" में है।

होउगल बताता है कि ऐसा कोई कार्य नहीं है। क्या आप व्यख्या कर सकते हैं?

यह आसान है, क्योंकि होगल को बेस लाइब्रेरीज़ में कोई फ़ंक्शन नहीं मिला जो उस प्रकार के हस्ताक्षर से मेल खाता है!

अधिक गंभीरता से, मुझे लगता है कि आप monadic स्पष्टीकरण के लिए पूछ रहे थे। मुद्दे सुरक्षा और अर्थ हैं। (my previous thoughts on magicMonadUnwrap :: Monad m => m a -> a भी देखें)

मान लीजिए कि मैं आपको बताता हूं कि मेरे पास एक मूल्य है जिसमें [Int] है। चूंकि हम जानते हैं कि [] एक मोनैड है, यह आपको यह बताने जैसा ही है कि मेरे पास एक मान है जिसमें Monad m => m Int है। तो मान लें कि आप उस [Int] में से Int प्राप्त करना चाहते हैं। खैर, कौन सा Int क्या आप चाहते हैं? पहले वाला? आखरी वाला? क्या होगा यदि मैंने आपको जो मूल्य बताया है वह वास्तव में एक खाली सूची है? उस स्थिति में, आपको देने के लिए Int भी नहीं है! तो सूचियों के लिए, यह असुरक्षित है जो इस तरह की एक सिंगल वैल्यू को निकालने और निकालने के लिए है। यहां तक ​​कि जब यह सुरक्षित है (एक गैर-खाली सूची), आपको f :: [Int] -> Int की इच्छा से माध्य को स्पष्ट करने के लिए आपको एक सूची-विशिष्ट फ़ंक्शन (उदाहरण के लिए, head) की आवश्यकता है। उम्मीद है कि आप यहां से खोज सकते हैं कि का अर्थात् अच्छी तरह परिभाषित नहीं है। यह एक ही मोनैड के लिए कई अर्थ रख सकता है, या इसका मतलब कुछ मोनैड के लिए बिल्कुल कुछ भी नहीं हो सकता है, और कभी-कभी, यह बस सुरक्षित नहीं है।

extract :: Monad m => m a -> a 

अब तुम इस तरह एक "समारोह" लिख सकते हैं::

+2

मुझे नहीं लगता कि कैसे 'मोनाड एम => एम ए -> ए' का अर्थ किसी भी तरह से नहीं है जो '>> =' या 'वापसी' या 'विफल' पर भी लागू नहीं होगा। आप हमेशा कह सकते हैं कि ऑपरेशन का "अर्थ" पूर्ण कार्यान्वयन को जानने के पहले अच्छी तरह परिभाषित नहीं है जो 'एम' मोनाड टाइप क्लास में शामिल करने के लिए प्रदान करता है। आपकी सूची उदाहरण के लिए, 'मोनैड एम => एम ए -> ए' टाइप करने वाला एक फ़ंक्शन आपके द्वारा सुझाए गए किसी भी चीज का बहुत अच्छा अर्थ हो सकता है - और उनमें से * * * * वैध हो सकता है। आप * अपने * एप्लिकेशन के व्यवहार को ट्विक करने के लिए हमेशा 'न्यूटाइप' का उपयोग कर सकते हैं, लेकिन ऐसा करने का मौका भी बहुत गंभीर लगता है। – ely

8

मान लीजिए वहाँ इस तरह के एक समारोह था

appendLine :: String -> String 
appendLine str = str ++ extract getLine 

जब तक extract समारोह गारंटी दी गई थी समाप्त करने के लिए कभी नहीं, इस संदर्भ का उल्लंघन होगा पारदर्शिता, क्योंकि appendLine "foo" का परिणाम होगा (ए) "foo" के अलावा किसी अन्य चीज़ पर निर्भर करता है, (बी) विभिन्न संदर्भों में मूल्यांकन करते समय विभिन्न मूल्यों का मूल्यांकन करता है।

या सरल शब्दों में, यदि वास्तव में उपयोगी extract ऑपरेशन होता है तो हास्केल पूरी तरह कार्यात्मक नहीं होगा।

+2

[unsafePerformIO] (http://hackage.haskell.org/package/base-4.7.0.1/docs/System-IO-Unsafe.html#v%3aunsafePerformIO) बस यही करता है। – ely

0

अच्छी तरह से, तकनीकी आईओ monad के लिए unsafePerformIO है।

लेकिन, जैसा कि नाम स्वयं ही सुझाव देता है, यह कार्य बुरा है और आपको केवल इसका उपयोग करना चाहिए यदि आप वास्तव में जानते हैं कि आप क्या कर रहे हैं (और यदि आपको गीले पूछना है या नहीं तो आप नहीं करते हैं)

+1

सूची मोनड के लिए 'असुरक्षित हैड' भी है ... (ओह रुको, इसे सिर्फ 'हेड' कहा जाता है ... लेकिन यह समान रूप से काफी हद तक असुरक्षित नहीं है।) –

+0

@ डैनबर्टन असल में, 'असुरक्षितफॉर्मियो' अक्सर सुरक्षित; यह चंद्रमा को नष्ट करने के लिए रॉकेट लॉन्च कर सकता है, लेकिन कम से कम यह आपके प्रोग्राम को दुर्घटनाग्रस्त नहीं करता है। – jpaugh

संबंधित मुद्दे