उस मामले के लिए unsafeInterleaveIO
या किसी आलसी आईओ का उपयोग न करें। यह ठीक है कि यह समस्या हल करने के लिए बनाई गई थी: आलसी आईओ से परहेज, जो अप्रत्याशित संसाधन प्रबंधन देता है। यह चाल कभी भी सूची का निर्माण नहीं करती है और जब तक आप इसका उपयोग नहीं कर लेते हैं तब तक इसे लगातार पुनरावृत्त करते हैं। मैं इसे प्रदर्शित करने के लिए, अपनी खुद की लाइब्रेरी, pipes
से उदाहरणों का उपयोग करूंगा।
सबसे पहले, निर्धारित करें:
import Control.Monad
import Control.Monad.Trans
import Control.Pipe
-- Demand only 'n' elements
take' :: (Monad m) => Int -> Pipe a a m()
take' n = replicateM_ n $ do
a <- await
yield a
-- Print all incoming elements
printer :: (Show a) => Consumer a IO r
printer = forever $ do
a <- await
lift $ print a
अब हमारे उपयोगकर्ता के लिए मतलब हो और मांग वे हमारे लिए बहुत बड़ी सूची का उत्पादन: अब
prompt100 :: Producer Int IO()
prompt100 = replicateM_ 1000 $ do
lift $ putStrLn "Enter an integer: "
n <- lift readLn
yield n
, चलो यह चलाते हैं:
>>> runPipe $ printer <+< take' 1 <+< prompt100
Enter an integer:
3<Enter>
3
यह केवल उपयोगकर्ता को एक पूर्णांक के लिए संकेत देता है, क्योंकि हम केवल एक पूर्णांक की मांग करते हैं!
आप getLargeList
से उत्पादन के साथ prompt100
बदलना चाहते हैं, तो आप सिर्फ लिखने:
yourProducer :: Producer b IO()
yourProducer = do
xs <- lift getLargeList
mapM_ yield xs
... और फिर चलाएँ:
>>> runPipe $ printer <+< take' 1 <+< yourProducer
यह lazily सूची स्ट्रीम और कभी नहीं का निर्माण करेगा स्मृति में सूची, सभी असुरक्षित IO
हैक का उपयोग किए बिना। यह बदलने के लिए कि आप कितने तत्व मांगते हैं, बस take'
इस तरह के अधिक उदाहरणों के लिए, pipes
tutorialControl.Pipe.Tutorial
पर पढ़ें।
आलसी आईओ समस्याओं का कारण बनने के बारे में और जानने के लिए, इस विषय पर ओलेग की मूल स्लाइड पढ़ें, जिसे आप here पा सकते हैं।वह आलसी आईओ का उपयोग करने में समस्याओं को समझाने का एक अच्छा काम करता है। किसी भी समय आप आलसी आईओ का उपयोग करने के लिए मजबूर महसूस करते हैं, जो आप वास्तव में चाहते हैं वह एक इटारेट लाइब्रेरी है।
शायद इससे मदद मिलेगी। http://stackoverflow.com/questions/3270255/is-haskells-mapm-not-lazy –
एंटोन, मैंने इस विषय को पढ़ा है, लेकिन मुझे जवाब नहीं मिला: क्या आलसी गणना के लिए mapM का एक विकल्प है। –
@DmitryBespalov एक ही प्रकार के हस्ताक्षर के साथ नहीं। 'मोनाड' में बाद में प्रभावों को परिभाषित करने के लिए एक अमूर्तता नहीं है - और यही है कि आपको 'mapM' को आलसी होने के लिए क्या करना होगा। – Carl