आप एक ऐसे फ़ंक्शन को परिभाषित कर सकते हैं जिसका प्रकार आप जो कहते हैं उससे मेल खाता है, हालांकि आम तौर पर।
import System.Random
randoms' :: (RandomGen g, Random a) => g -> Int -> ([a], g)
randoms' g n =
let (g1, g2) = split g
in (take n $ randoms g1, g2)
हालांकि इसे इस्तेमाल करता है split
split :: g -> (g, g)
split
आपरेशन एक दो अलग यादृच्छिक संख्या जनरेटर प्राप्त करने के लिए अनुमति देता है। यह कार्यात्मक कार्यक्रमों में बहुत उपयोगी है (उदाहरण के लिए, रिकर्सिव कॉल करने के लिए यादृच्छिक संख्या जेनरेटर पास करते समय), लेकिन split
और नरक के सांख्यिकीय रूप से मजबूत कार्यान्वयन पर बहुत कम काम किया गया है;
यह अभी भी आप जो चाहते हैं वह नहीं करता है। (मैं आसान दृश्य तुलना के लिए नीचे दिए गए उदाहरण में Bool
का उपयोग करें।)
ghci> g <- getStdGen
ghci> randoms' g 5 :: ([Bool], StdGen)
([False,False,False,True,False],1648254783 2147483398)
ghci> randoms' g 5 :: ([Bool], StdGen)
([False,False,False,True,False],1648254783 2147483398)
ध्यान दें कि यादृच्छिक सरणियों ही हैं।
हालांकि यह कार्य जनरेटर को विभाजित करने की दिक्कत पर जाता है, हम तुरंत इसे त्याग देते हैं। इसके बजाय, अपने कोड IO
इकाई में चल रहा है बाद में कॉल करने के लिए यह
ghci> let (a1,g2) = randoms' g 5 :: ([Bool], StdGen)
ghci> let (a2,_) = randoms' g2 5 :: ([Bool], StdGen)
ghci> (a1,a2)
([False,False,False,True,False],[True,True,True,False,True]
में के रूप में सूत्रण द्वारा g2
का इस्तेमाल करते हैं, तो आप उपयोग कर सकते हैं setStdGen
के रूप में, अंत में वैश्विक यादृच्छिक संख्या जनरेटर को बदलने के लिए
myAction :: Int -> IO ([Float],[Float])
myAction n = do
g <- getStdGen
let (f1,g2) = randoms' g n
let (f2,g3) = randoms' g2 n
setStdGen g3
return (f1, f2)
आसपास के थ्रेडिंग राज्य अजीब और त्रुटि-प्रवण है। State
या ST
का उपयोग करने पर विचार करें यदि आपके पास बहुत सारे बार बॉयलरप्लेट हैं।
एक और विकल्प ['split'] (http://hackage.haskell.org/packages/archive/random/latest/doc/html/System-Random.html#v:split) जेनरेटर दो में है। फिर आप परिणामी जेनरेटर में से एक को 'रैंडम्स' कॉल करने और दूसरे के साथ जारी रखने के लिए उपयोग कर सकते हैं। यह अनंत सूचियों के साथ भी काम करता है। – hammar