निम्नलिखित कार्यक्रम सही ढंग से समाप्त हो जाता है:हैस्केल में mapM सख्त है? इस कार्यक्रम को एक ढेर ओवरफ्लो क्यों मिलता है?
import System.Random
randomList = mapM (\_->getStdRandom (randomR (0, 50000::Int))) [0..5000]
main = do
randomInts <- randomList
print $ take 5 randomInts
रनिंग:
$ runhaskell test.hs
[26156,7258,29057,40002,26339]
हालांकि, एक अनंत सूची के साथ यह भोजन, कार्यक्रम कभी नहीं समाप्त हो जाता है, और जब संकलित है, अंत में एक ढेर अतिप्रवाह त्रुटि देता है!
import System.Random
randomList = mapM (\_->getStdRandom (randomR (0, 50000::Int))) [0..]
main = do
randomInts <- randomList
print $ take 5 randomInts
चल रहा है,
$ ./test
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.
मैं इस कार्यक्रम lazily getStdRandom
मूल्यांकन करने के लिए हर बार जब मैं सूची से एक आइटम लेने, तो 5 बार करने के बाद खत्म कर की उम्मीद। यह पूरी सूची का मूल्यांकन करने की कोशिश क्यों कर रहा है?
धन्यवाद।
क्या यादृच्छिक संख्याओं की अनंत सूची प्राप्त करने का कोई बेहतर तरीका है? मैं इस सूची को एक शुद्ध समारोह में पास करना चाहता हूं।
संपादित करें: कुछ और पढ़ने से पता चला समारोह
randomList r = do g <- getStdGen
return $ randomRs r g
मैं के लिए क्या देख रहा था है।
EDIT2: कैमकैन के उत्तर पढ़ने के बाद, मुझे एहसास हुआ कि getStdGen
प्रत्येक कॉल पर एक नया बीज प्राप्त कर रहा है। इसके बजाय, बेहतर एक सरल एक शॉट यादृच्छिक सूची जनरेटर के रूप में इस सुविधा का उपयोग करने के लिए:
import System.Random
randomList :: Random a => a -> a -> IO [a]
randomList r g = do s <- newStdGen
return $ randomRs (r,g) s
main = do r <- randomList 0 (50::Int)
print $ take 5 r
लेकिन मैं अभी भी समझ में नहीं आता क्यों मेरे mapM
कॉल समाप्त नहीं किया। स्पष्ट रूप से यादृच्छिक संख्या से संबंधित नहीं है, लेकिन mapM
के साथ कुछ करने के लिए शायद।
उदाहरण के लिए, मैंने पाया कि निम्नलिखित भी समाप्त नहीं करता:
randomList = mapM (\_->return 0) [0..]
main = do
randomInts <- randomList
print $ take 50000 randomInts
क्या देता है? वैसे, आईएमएचओ, उपर्युक्त randomInts
फ़ंक्शन System.Random
में होना चाहिए। यह बहुत सुविधाजनक है कि बस आईओ मोनैड में एक यादृच्छिक सूची उत्पन्न करें और आवश्यकता होने पर इसे शुद्ध कार्य में पास करें, मुझे नहीं लगता कि यह मानक पुस्तकालय में क्यों नहीं होना चाहिए।
ओह, और मेरा उत्तर के परिशिष्ट के रूप: तुम बस '\ r के रूप में' randomInts' की एक अधिक सामान्य संस्करण लिख सकें -> FMAP (randomRs r) getStdGen'। इसमें टाइप '(रैंडम ए) => (ए, ए) -> आईओ [ए] 'है, दूसरे शब्दों में, यह किसी भी प्रकार के लिए रैंडम मानों की एक सूची उत्पन्न करता है जो' रैंडम 'का उदाहरण है। –
यहां तक कि बेहतर, धन्यवाद। – Steve
मुझे लगता है कि यही कारण है कि मेरा 'यादृच्छिक सूची' फ़ंक्शन को मानक lib में भी होने की आवश्यकता नहीं होगी, अगर वह छोटा हो, लेकिन लड़का यह स्पष्ट नहीं है कि इसे एक नए के लिए कैसे लिखना है;) तो मुझे अभी भी लगता है कि यह होना चाहिए सुविधा के लिए वहाँ .. – Steve