मेरे पास सी में कुछ फ़ंक्शन लिखे गए हैं जिन्हें मैं हास्केल से कॉल करता हूं। ये फ़ंक्शन IO (CInt)
लौटाते हैं। कभी-कभी मैं उन सभी कार्यों को चलाने के लिए चाहता हूं चाहे वे उनमें से कोई भी वापस आएं, और यह आसान है। उदाहरण के कोड के लिए, यह वर्तमान में क्या हो रहा है के सामान्य विचार है:हास्केल: मोनैडिक लेते समय?
Prelude> let f x = print x >> return x
Prelude> mapM_ f [0..5]
0
1
2
3
4
5
Prelude>
मैं अपने वांछित साइड इफेक्ट मिलता है, और मैं परिणाम के बारे में परवाह नहीं है। लेकिन अब मुझे पहले आइटम के तुरंत बाद निष्पादन रोकना होगा जो मेरा वांछित परिणाम नहीं लौटाता है। - मान लीजिए 4 या उच्चतर की वापसी मूल्य को रोकने के लिए निष्पादन की आवश्यकता तो है कि मैं क्या चाहते करने के लिए यह है:
Prelude> takeWhile (<4) $ mapM f [0..5]
कौन मुझे इस त्रुटि देता है:
<interactive>:1:22: Couldn't match expected type `[b]' against inferred type `IO a' In the first argument of `mapM', namely `f' In the second argument of `($)', namely `mapM f ([0 .. 5])' In the expression: takeWhile (< 4) $ mapM f ([0 .. 5])
और वह करने के लिए समझ में आता है मैं - परिणाम अभी भी आईओ monad में निहित है, और मैं सिर्फ आईओ monad में निहित दो मूल्यों की तुलना नहीं कर सकता। मुझे पता है कि यह मोनाड्स का उद्देश्य है - एक निश्चित स्थिति को पूरा करते समय एक साथ परिणाम चेनिंग और संचालन को छोड़ना - लेकिन इस मामले में आईओ मोनैड को "लपेटने" का एक आसान तरीका है, इस स्थिति में श्रृंखला को निष्पादित करना बंद करना MonadPlus
का उदाहरण लिखने के बिना, मेरे चयन का?
क्या मैं टेक के समय के प्रयोजनों के लिए f
से मूल्यों को "अनलिफ्ट" कर सकता हूं?
क्या यह एक समाधान है जहां मकान मालिक फिट बैठते हैं? फ़ैक्टर ने अभी तक मेरे साथ "क्लिक नहीं किया" है, लेकिन मुझे लगता है कि यह इंप्रेशन है कि यह उनका उपयोग करने के लिए एक अच्छी स्थिति हो सकती है।
अद्यतन:
@sth जो मैं चाहता के लिए निकटतम उत्तर है - वास्तव में, यह है कि लगभग वास्तव में क्या मैं के लिए जा रहा था, लेकिन मैं अभी भी है कि क्या वहाँ एक देखना चाहते हैं मानक समाधान जो स्पष्ट रूप से रिकर्सिव नहीं है - यह हास्केल है, आखिरकार! इस बात पर वापस देखकर कि मैंने अपने प्रश्न कैसे कहा, अब मैं देख सकता हूं कि मैं अपने वांछित व्यवहार के बारे में पर्याप्त स्पष्ट नहीं था।
f
फ़ंक्शन मैंने उदाहरण के लिए ऊपर उपयोग किया था केवल एक उदाहरण था। वास्तविक कार्य सी में लिखे गए हैं और विशेष रूप से उनके दुष्प्रभावों के लिए उपयोग किए जाते हैं। मैं mapM_ f (takeWhile (<4) [0..5])
के @ टॉम के सुझाव का उपयोग नहीं कर सकता क्योंकि मुझे पता नहीं है कि निष्पादित होने तक कोई इनपुट वास्तव में सफलता या विफलता का परिणाम देगा या नहीं।
मुझे वास्तव में लौटाई गई सूची के बारे में परवाह नहीं है, या तो मैं सी कार्य को तब तक कॉल करना चाहता हूं जब तक सूची समाप्त न हो या पहले सी फ़ंक्शन विफलता कोड लौटाए।
सी शैली स्यूडोकोड में, मेरा व्यवहार होगा:
do {
result = function_with_side_effects(input_list[index++]);
} while (result == success && index < max_index);
तो फिर, @ sth का जवाब, सही व्यवहार है कि मैं चाहता हूँ करता है, सिवाय इसके कि परिणाम खारिज किया जा सकता (चाहिए?)। एक dropWhileM_
फ़ंक्शन मेरे उद्देश्यों के बराबर होगा। Control.Monad में ऐसा कोई फ़ंक्शन क्यों नहीं है या takeWhileM_
क्यों नहीं है? मैं देखता हूं कि a similar discussion on a mailing list था, लेकिन ऐसा लगता है कि इसमें से कुछ भी नहीं आया है।
यह भी थोड़ा निराशाजनक है कि 'sortBy' को' sortByM :: Monad m => (a -> a -> m ऑर्डरिंग) के संदर्भ में परिभाषित नहीं किया गया है -> [a] -> m [a] '। –