<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ --> <title>System/Random.hs</title> <link type='text/css' rel='stylesheet' href='hscolour.css' /> </head> <body> <pre><a name="line-1"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span> <a name="line-2"></a><span class='hs-comment'>-- |</span> <a name="line-3"></a><span class='hs-comment'>-- Module : System.Random</span> <a name="line-4"></a><span class='hs-comment'>-- Copyright : (c) The University of Glasgow 2001</span> <a name="line-5"></a><span class='hs-comment'>-- License : BSD-style (see the file libraries/base/LICENSE)</span> <a name="line-6"></a><span class='hs-comment'>-- </span> <a name="line-7"></a><span class='hs-comment'>-- Maintainer : libraries@haskell.org</span> <a name="line-8"></a><span class='hs-comment'>-- Stability : stable</span> <a name="line-9"></a><span class='hs-comment'>-- Portability : portable</span> <a name="line-10"></a><span class='hs-comment'>--</span> <a name="line-11"></a><span class='hs-comment'>-- This library deals with the common task of pseudo-random number</span> <a name="line-12"></a><span class='hs-comment'>-- generation. The library makes it possible to generate repeatable</span> <a name="line-13"></a><span class='hs-comment'>-- results, by starting with a specified initial random number generator,</span> <a name="line-14"></a><span class='hs-comment'>-- or to get different results on each run by using the system-initialised</span> <a name="line-15"></a><span class='hs-comment'>-- generator or by supplying a seed from some other source.</span> <a name="line-16"></a><span class='hs-comment'>--</span> <a name="line-17"></a><span class='hs-comment'>-- The library is split into two layers: </span> <a name="line-18"></a><span class='hs-comment'>--</span> <a name="line-19"></a><span class='hs-comment'>-- * A core /random number generator/ provides a supply of bits.</span> <a name="line-20"></a><span class='hs-comment'>-- The class 'RandomGen' provides a common interface to such generators.</span> <a name="line-21"></a><span class='hs-comment'>-- The library provides one instance of 'RandomGen', the abstract</span> <a name="line-22"></a><span class='hs-comment'>-- data type 'StdGen'. Programmers may, of course, supply their own</span> <a name="line-23"></a><span class='hs-comment'>-- instances of 'RandomGen'.</span> <a name="line-24"></a><span class='hs-comment'>--</span> <a name="line-25"></a><span class='hs-comment'>-- * The class 'Random' provides a way to extract values of a particular</span> <a name="line-26"></a><span class='hs-comment'>-- type from a random number generator. For example, the 'Float'</span> <a name="line-27"></a><span class='hs-comment'>-- instance of 'Random' allows one to generate random values of type</span> <a name="line-28"></a><span class='hs-comment'>-- 'Float'.</span> <a name="line-29"></a><span class='hs-comment'>--</span> <a name="line-30"></a><span class='hs-comment'>-- This implementation uses the Portable Combined Generator of L'Ecuyer</span> <a name="line-31"></a><span class='hs-comment'>-- ["System.Random\#LEcuyer"] for 32-bit computers, transliterated by</span> <a name="line-32"></a><span class='hs-comment'>-- Lennart Augustsson. It has a period of roughly 2.30584e18.</span> <a name="line-33"></a><span class='hs-comment'>--</span> <a name="line-34"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span> <a name="line-35"></a> <a name="line-36"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>Random</span> <a name="line-37"></a> <span class='hs-layout'>(</span> <a name="line-38"></a> <a name="line-39"></a> <span class='hs-comment'>-- $intro</span> <a name="line-40"></a> <a name="line-41"></a> <span class='hs-comment'>-- * Random number generators</span> <a name="line-42"></a> <a name="line-43"></a> <span class='hs-conid'>RandomGen</span><span class='hs-layout'>(</span><span class='hs-varid'>next</span><span class='hs-layout'>,</span> <span class='hs-varid'>split</span><span class='hs-layout'>,</span> <span class='hs-varid'>genRange</span><span class='hs-layout'>)</span> <a name="line-44"></a> <a name="line-45"></a> <span class='hs-comment'>-- ** Standard random number generators</span> <a name="line-46"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>StdGen</span> <a name="line-47"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>mkStdGen</span> <a name="line-48"></a> <a name="line-49"></a> <span class='hs-comment'>-- ** The global random number generator</span> <a name="line-50"></a> <a name="line-51"></a> <span class='hs-comment'>-- $globalrng</span> <a name="line-52"></a> <a name="line-53"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>getStdRandom</span> <a name="line-54"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>getStdGen</span> <a name="line-55"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>setStdGen</span> <a name="line-56"></a> <span class='hs-layout'>,</span> <span class='hs-varid'>newStdGen</span> <a name="line-57"></a> <a name="line-58"></a> <span class='hs-comment'>-- * Random values of various types</span> <a name="line-59"></a> <span class='hs-layout'>,</span> <span class='hs-conid'>Random</span> <span class='hs-layout'>(</span> <span class='hs-varid'>random</span><span class='hs-layout'>,</span> <span class='hs-varid'>randomR</span><span class='hs-layout'>,</span> <a name="line-60"></a> <span class='hs-varid'>randoms</span><span class='hs-layout'>,</span> <span class='hs-varid'>randomRs</span><span class='hs-layout'>,</span> <a name="line-61"></a> <span class='hs-varid'>randomIO</span><span class='hs-layout'>,</span> <span class='hs-varid'>randomRIO</span> <span class='hs-layout'>)</span> <a name="line-62"></a> <a name="line-63"></a> <span class='hs-comment'>-- * References</span> <a name="line-64"></a> <span class='hs-comment'>-- $references</span> <a name="line-65"></a> <a name="line-66"></a> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span> <a name="line-67"></a> <a name="line-68"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <a name="line-69"></a> <a name="line-70"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Int</span> <a name="line-71"></a> <a name="line-72"></a><span class='hs-cpp'>#ifdef __NHC__</span> <a name="line-73"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CPUTime</span> <span class='hs-layout'>(</span> <span class='hs-varid'>getCPUTime</span> <span class='hs-layout'>)</span> <a name="line-74"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Foreign</span><span class='hs-varop'>.</span><span class='hs-conid'>Ptr</span> <span class='hs-layout'>(</span> <span class='hs-conid'>Ptr</span><span class='hs-layout'>,</span> <span class='hs-varid'>nullPtr</span> <span class='hs-layout'>)</span> <a name="line-75"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Foreign</span><span class='hs-varop'>.</span><span class='hs-conid'>C</span> <span class='hs-layout'>(</span> <span class='hs-conid'>CTime</span><span class='hs-layout'>,</span> <span class='hs-conid'>CUInt</span> <span class='hs-layout'>)</span> <a name="line-76"></a><span class='hs-cpp'>#else</span> <a name="line-77"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>CPUTime</span> <span class='hs-layout'>(</span> <span class='hs-varid'>getCPUTime</span> <span class='hs-layout'>)</span> <a name="line-78"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Time</span> <span class='hs-layout'>(</span> <span class='hs-varid'>getCurrentTime</span><span class='hs-layout'>,</span> <span class='hs-conid'>UTCTime</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span> <span class='hs-layout'>)</span> <a name="line-79"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Ratio</span> <span class='hs-layout'>(</span> <span class='hs-varid'>numerator</span><span class='hs-layout'>,</span> <span class='hs-varid'>denominator</span> <span class='hs-layout'>)</span> <a name="line-80"></a><span class='hs-cpp'>#endif</span> <a name="line-81"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>Char</span> <span class='hs-layout'>(</span> <span class='hs-varid'>isSpace</span><span class='hs-layout'>,</span> <span class='hs-varid'>chr</span><span class='hs-layout'>,</span> <span class='hs-varid'>ord</span> <span class='hs-layout'>)</span> <a name="line-82"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>System</span><span class='hs-varop'>.</span><span class='hs-conid'>IO</span><span class='hs-varop'>.</span><span class='hs-conid'>Unsafe</span> <span class='hs-layout'>(</span> <span class='hs-varid'>unsafePerformIO</span> <span class='hs-layout'>)</span> <a name="line-83"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>IORef</span> <a name="line-84"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Numeric</span> <span class='hs-layout'>(</span> <span class='hs-varid'>readDec</span> <span class='hs-layout'>)</span> <a name="line-85"></a> <a name="line-86"></a><span class='hs-comment'>-- The standard nhc98 implementation of Time.ClockTime does not match</span> <a name="line-87"></a><span class='hs-comment'>-- the extended one expected in this module, so we lash-up a quick</span> <a name="line-88"></a><span class='hs-comment'>-- replacement here.</span> <a name="line-89"></a><span class='hs-cpp'>#ifdef __NHC__</span> <a name="line-90"></a><span class='hs-keyword'>foreign</span> <span class='hs-keyword'>import</span> <span class='hs-keyword'>ccall</span> <span class='hs-str'>"time.h time"</span> <span class='hs-varid'>readtime</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Ptr</span> <span class='hs-conid'>CTime</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>CTime</span> <a name="line-91"></a><a name="getTime"></a><span class='hs-definition'>getTime</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Integer</span><span class='hs-layout'>,</span> <span class='hs-conid'>Integer</span><span class='hs-layout'>)</span> <a name="line-92"></a><span class='hs-definition'>getTime</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-conid'>CTime</span> <span class='hs-varid'>t</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>readtime</span> <span class='hs-varid'>nullPtr</span><span class='hs-layout'>;</span> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>toInteger</span> <span class='hs-varid'>t</span><span class='hs-layout'>,</span> <span class='hs-num'>0</span><span class='hs-layout'>)</span> <a name="line-93"></a><span class='hs-cpp'>#else</span> <a name="line-94"></a><span class='hs-definition'>getTime</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-layout'>(</span><span class='hs-conid'>Integer</span><span class='hs-layout'>,</span> <span class='hs-conid'>Integer</span><span class='hs-layout'>)</span> <a name="line-95"></a><span class='hs-definition'>getTime</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-96"></a> <span class='hs-varid'>utc</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>getCurrentTime</span> <a name="line-97"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>daytime</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>toRational</span> <span class='hs-varop'>$</span> <span class='hs-varid'>utctDayTime</span> <span class='hs-varid'>utc</span> <a name="line-98"></a> <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-varid'>quotRem</span> <span class='hs-layout'>(</span><span class='hs-varid'>numerator</span> <span class='hs-varid'>daytime</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>denominator</span> <span class='hs-varid'>daytime</span><span class='hs-layout'>)</span> <a name="line-99"></a><span class='hs-cpp'>#endif</span> <a name="line-100"></a> <a name="line-101"></a><span class='hs-comment'>-- | The class 'RandomGen' provides a common interface to random number</span> <a name="line-102"></a><span class='hs-comment'>-- generators.</span> <a name="line-103"></a><span class='hs-comment'>--</span> <a name="line-104"></a><span class='hs-comment'>-- Minimal complete definition: 'next' and 'split'.</span> <a name="line-105"></a> <a name="line-106"></a><a name="RandomGen"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span> <span class='hs-keyword'>where</span> <a name="line-107"></a> <a name="line-108"></a> <span class='hs-comment'>-- |The 'next' operation returns an 'Int' that is uniformly distributed</span> <a name="line-109"></a> <span class='hs-comment'>-- in the range returned by 'genRange' (including both end points),</span> <a name="line-110"></a> <span class='hs-comment'>-- and a new generator.</span> <a name="line-111"></a> <span class='hs-varid'>next</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-112"></a> <a name="line-113"></a> <span class='hs-comment'>-- |The 'split' operation allows one to obtain two distinct random number</span> <a name="line-114"></a> <span class='hs-comment'>-- generators. This is very useful in functional programs (for example, when</span> <a name="line-115"></a> <span class='hs-comment'>-- passing a random number generator down to recursive calls), but very</span> <a name="line-116"></a> <span class='hs-comment'>-- little work has been done on statistically robust implementations of</span> <a name="line-117"></a> <span class='hs-comment'>-- 'split' (["System.Random\#Burton", "System.Random\#Hellekalek"]</span> <a name="line-118"></a> <span class='hs-comment'>-- are the only examples we know of).</span> <a name="line-119"></a> <span class='hs-varid'>split</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>g</span><span class='hs-layout'>,</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-120"></a> <a name="line-121"></a> <span class='hs-comment'>-- |The 'genRange' operation yields the range of values returned by</span> <a name="line-122"></a> <span class='hs-comment'>-- the generator.</span> <a name="line-123"></a> <span class='hs-comment'>--</span> <a name="line-124"></a> <span class='hs-comment'>-- It is required that:</span> <a name="line-125"></a> <span class='hs-comment'>--</span> <a name="line-126"></a> <span class='hs-comment'>-- * If @(a,b) = 'genRange' g@, then @a < b@.</span> <a name="line-127"></a> <span class='hs-comment'>--</span> <a name="line-128"></a> <span class='hs-comment'>-- * 'genRange' always returns a pair of defined 'Int's.</span> <a name="line-129"></a> <span class='hs-comment'>--</span> <a name="line-130"></a> <span class='hs-comment'>-- The second condition ensures that 'genRange' cannot examine its</span> <a name="line-131"></a> <span class='hs-comment'>-- argument, and hence the value it returns can be determined only by the</span> <a name="line-132"></a> <span class='hs-comment'>-- instance of 'RandomGen'. That in turn allows an implementation to make</span> <a name="line-133"></a> <span class='hs-comment'>-- a single call to 'genRange' to establish a generator's range, without</span> <a name="line-134"></a> <span class='hs-comment'>-- being concerned that the generator returned by (say) 'next' might have</span> <a name="line-135"></a> <span class='hs-comment'>-- a different range to the generator passed to 'next'.</span> <a name="line-136"></a> <span class='hs-comment'>--</span> <a name="line-137"></a> <span class='hs-comment'>-- The default definition spans the full range of 'Int'.</span> <a name="line-138"></a> <span class='hs-varid'>genRange</span> <span class='hs-keyglyph'>::</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span><span class='hs-conid'>Int</span><span class='hs-layout'>)</span> <a name="line-139"></a> <a name="line-140"></a> <span class='hs-comment'>-- default method</span> <a name="line-141"></a> <span class='hs-varid'>genRange</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>minBound</span><span class='hs-layout'>,</span> <span class='hs-varid'>maxBound</span><span class='hs-layout'>)</span> <a name="line-142"></a> <a name="line-143"></a><span class='hs-comment'>{- | <a name="line-144"></a>The 'StdGen' instance of 'RandomGen' has a 'genRange' of at least 30 bits. <a name="line-145"></a> <a name="line-146"></a>The result of repeatedly using 'next' should be at least as statistically <a name="line-147"></a>robust as the /Minimal Standard Random Number Generator/ described by <a name="line-148"></a>["System.Random\#Park", "System.Random\#Carta"]. <a name="line-149"></a>Until more is known about implementations of 'split', all we require is <a name="line-150"></a>that 'split' deliver generators that are (a) not identical and <a name="line-151"></a>(b) independently robust in the sense just given. <a name="line-152"></a> <a name="line-153"></a>The 'Show' and 'Read' instances of 'StdGen' provide a primitive way to save the <a name="line-154"></a>state of a random number generator. <a name="line-155"></a>It is required that @'read' ('show' g) == g@. <a name="line-156"></a> <a name="line-157"></a>In addition, 'reads' may be used to map an arbitrary string (not necessarily one <a name="line-158"></a>produced by 'show') onto a value of type 'StdGen'. In general, the 'Read' <a name="line-159"></a>instance of 'StdGen' has the following properties: <a name="line-160"></a> <a name="line-161"></a>* It guarantees to succeed on any string. <a name="line-162"></a> <a name="line-163"></a>* It guarantees to consume only a finite portion of the string. <a name="line-164"></a> <a name="line-165"></a>* Different argument strings are likely to result in different results. <a name="line-166"></a> <a name="line-167"></a>-}</span> <a name="line-168"></a> <a name="line-169"></a><a name="StdGen"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>StdGen</span> <a name="line-170"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StdGen</span> <span class='hs-conid'>Int32</span> <span class='hs-conid'>Int32</span> <a name="line-171"></a> <a name="line-172"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>RandomGen</span> <span class='hs-conid'>StdGen</span> <span class='hs-keyword'>where</span> <a name="line-173"></a> <span class='hs-varid'>next</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>stdNext</span> <a name="line-174"></a> <span class='hs-varid'>split</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>stdSplit</span> <a name="line-175"></a> <span class='hs-varid'>genRange</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>stdRange</span> <a name="line-176"></a> <a name="line-177"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Show</span> <span class='hs-conid'>StdGen</span> <span class='hs-keyword'>where</span> <a name="line-178"></a> <span class='hs-varid'>showsPrec</span> <span class='hs-varid'>p</span> <span class='hs-layout'>(</span><span class='hs-conid'>StdGen</span> <span class='hs-varid'>s1</span> <span class='hs-varid'>s2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <a name="line-179"></a> <span class='hs-varid'>showsPrec</span> <span class='hs-varid'>p</span> <span class='hs-varid'>s1</span> <span class='hs-varop'>.</span> <a name="line-180"></a> <span class='hs-varid'>showChar</span> <span class='hs-chr'>' '</span> <span class='hs-varop'>.</span> <a name="line-181"></a> <span class='hs-varid'>showsPrec</span> <span class='hs-varid'>p</span> <span class='hs-varid'>s2</span> <a name="line-182"></a> <a name="line-183"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Read</span> <span class='hs-conid'>StdGen</span> <span class='hs-keyword'>where</span> <a name="line-184"></a> <span class='hs-varid'>readsPrec</span> <span class='hs-sel'>_p</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>\</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>-></span> <a name="line-185"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>try_read</span> <span class='hs-varid'>r</span> <span class='hs-keyword'>of</span> <a name="line-186"></a> <span class='hs-varid'>r'</span><span class='hs-keyglyph'>@</span><span class='hs-keyglyph'>[</span><span class='hs-keyword'>_</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>r'</span> <a name="line-187"></a> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>stdFromString</span> <span class='hs-varid'>r</span><span class='hs-keyglyph'>]</span> <span class='hs-comment'>-- because it shouldn't ever fail.</span> <a name="line-188"></a> <span class='hs-keyword'>where</span> <a name="line-189"></a> <span class='hs-varid'>try_read</span> <span class='hs-varid'>r</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-190"></a> <span class='hs-layout'>(</span><span class='hs-varid'>s1</span><span class='hs-layout'>,</span> <span class='hs-varid'>r1</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>readDec</span> <span class='hs-layout'>(</span><span class='hs-varid'>dropWhile</span> <span class='hs-varid'>isSpace</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <a name="line-191"></a> <span class='hs-layout'>(</span><span class='hs-varid'>s2</span><span class='hs-layout'>,</span> <span class='hs-varid'>r2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>readDec</span> <span class='hs-layout'>(</span><span class='hs-varid'>dropWhile</span> <span class='hs-varid'>isSpace</span> <span class='hs-varid'>r1</span><span class='hs-layout'>)</span> <a name="line-192"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-conid'>StdGen</span> <span class='hs-varid'>s1</span> <span class='hs-varid'>s2</span><span class='hs-layout'>,</span> <span class='hs-varid'>r2</span><span class='hs-layout'>)</span> <a name="line-193"></a> <a name="line-194"></a><a name="stdFromString"></a><span class='hs-comment'>{- <a name="line-195"></a> If we cannot unravel the StdGen from a string, create <a name="line-196"></a> one based on the string given. <a name="line-197"></a>-}</span> <a name="line-198"></a><span class='hs-definition'>stdFromString</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>StdGen</span><span class='hs-layout'>,</span> <span class='hs-conid'>String</span><span class='hs-layout'>)</span> <a name="line-199"></a><span class='hs-definition'>stdFromString</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkStdGen</span> <span class='hs-varid'>num</span><span class='hs-layout'>,</span> <span class='hs-varid'>rest</span><span class='hs-layout'>)</span> <a name="line-200"></a> <span class='hs-keyword'>where</span> <span class='hs-layout'>(</span><span class='hs-varid'>cs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rest</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitAt</span> <span class='hs-num'>6</span> <span class='hs-varid'>s</span> <a name="line-201"></a> <span class='hs-varid'>num</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldl</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>a</span> <span class='hs-varid'>x</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>x</span> <span class='hs-varop'>+</span> <span class='hs-num'>3</span> <span class='hs-varop'>*</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-num'>1</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>ord</span> <span class='hs-varid'>cs</span><span class='hs-layout'>)</span> <a name="line-202"></a> <a name="line-203"></a> <a name="line-204"></a><a name="mkStdGen"></a><span class='hs-comment'>{- | <a name="line-205"></a>The function 'mkStdGen' provides an alternative way of producing an initial <a name="line-206"></a>generator, by mapping an 'Int' into a generator. Again, distinct arguments <a name="line-207"></a>should be likely to produce distinct generators. <a name="line-208"></a>-}</span> <a name="line-209"></a><span class='hs-definition'>mkStdGen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>StdGen</span> <span class='hs-comment'>-- why not Integer ?</span> <a name="line-210"></a><span class='hs-definition'>mkStdGen</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkStdGen32</span> <span class='hs-varop'>$</span> <span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>s</span> <a name="line-211"></a> <a name="line-212"></a><a name="mkStdGen32"></a><span class='hs-definition'>mkStdGen32</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int32</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>StdGen</span> <a name="line-213"></a><span class='hs-definition'>mkStdGen32</span> <span class='hs-varid'>s</span> <a name="line-214"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>s</span> <span class='hs-varop'><</span> <span class='hs-num'>0</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkStdGen32</span> <span class='hs-layout'>(</span><span class='hs-comment'>-</span><span class='hs-varid'>s</span><span class='hs-layout'>)</span> <a name="line-215"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StdGen</span> <span class='hs-layout'>(</span><span class='hs-varid'>s1</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>s2</span><span class='hs-varop'>+</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <a name="line-216"></a> <span class='hs-keyword'>where</span> <a name="line-217"></a> <span class='hs-layout'>(</span><span class='hs-varid'>q</span><span class='hs-layout'>,</span> <span class='hs-varid'>s1</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s</span> <span class='hs-varop'>`divMod`</span> <span class='hs-num'>2147483562</span> <a name="line-218"></a> <span class='hs-varid'>s2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>q</span> <span class='hs-varop'>`mod`</span> <span class='hs-num'>2147483398</span> <a name="line-219"></a> <a name="line-220"></a><a name="createStdGen"></a><span class='hs-definition'>createStdGen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>StdGen</span> <a name="line-221"></a><span class='hs-definition'>createStdGen</span> <span class='hs-varid'>s</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkStdGen32</span> <span class='hs-varop'>$</span> <span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>s</span> <a name="line-222"></a> <a name="line-223"></a><span class='hs-comment'>-- FIXME: 1/2/3 below should be ** (vs@30082002) XXX</span> <a name="line-224"></a> <a name="line-225"></a><span class='hs-comment'>{- | <a name="line-226"></a>With a source of random number supply in hand, the 'Random' class allows the <a name="line-227"></a>programmer to extract random values of a variety of types. <a name="line-228"></a> <a name="line-229"></a>Minimal complete definition: 'randomR' and 'random'. <a name="line-230"></a> <a name="line-231"></a>-}</span> <a name="line-232"></a> <a name="line-233"></a><span class='hs-keyword'>class</span> <span class='hs-conid'>Random</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>where</span> <a name="line-234"></a> <span class='hs-comment'>-- | Takes a range /(lo,hi)/ and a random number generator</span> <a name="line-235"></a> <span class='hs-comment'>-- /g/, and returns a random value uniformly distributed in the closed</span> <a name="line-236"></a> <span class='hs-comment'>-- interval /[lo,hi]/, together with a new generator. It is unspecified</span> <a name="line-237"></a> <span class='hs-comment'>-- what happens if /lo>hi/. For continuous types there is no requirement</span> <a name="line-238"></a> <span class='hs-comment'>-- that the values /lo/ and /hi/ are ever produced, but they may be,</span> <a name="line-239"></a> <span class='hs-comment'>-- depending on the implementation and the interval.</span> <a name="line-240"></a> <span class='hs-varid'>randomR</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=></span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-241"></a> <a name="line-242"></a> <span class='hs-comment'>-- | The same as 'randomR', but using a default range determined by the type:</span> <a name="line-243"></a> <span class='hs-comment'>--</span> <a name="line-244"></a> <span class='hs-comment'>-- * For bounded types (instances of 'Bounded', such as 'Char'),</span> <a name="line-245"></a> <span class='hs-comment'>-- the range is normally the whole type.</span> <a name="line-246"></a> <span class='hs-comment'>--</span> <a name="line-247"></a> <span class='hs-comment'>-- * For fractional types, the range is normally the semi-closed interval</span> <a name="line-248"></a> <span class='hs-comment'>-- @[0,1)@.</span> <a name="line-249"></a> <span class='hs-comment'>--</span> <a name="line-250"></a> <span class='hs-comment'>-- * For 'Integer', the range is (arbitrarily) the range of 'Int'.</span> <a name="line-251"></a> <span class='hs-varid'>random</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=></span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-252"></a> <a name="line-253"></a> <span class='hs-comment'>-- | Plural variant of 'randomR', producing an infinite list of</span> <a name="line-254"></a> <span class='hs-comment'>-- random values instead of returning a new generator.</span> <a name="line-255"></a> <span class='hs-varid'>randomRs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=></span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <a name="line-256"></a> <span class='hs-varid'>randomRs</span> <span class='hs-varid'>ival</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>x</span> <span class='hs-conop'>:</span> <span class='hs-varid'>randomRs</span> <span class='hs-varid'>ival</span> <span class='hs-varid'>g'</span> <span class='hs-keyword'>where</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-layout'>,</span><span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomR</span> <span class='hs-varid'>ival</span> <span class='hs-varid'>g</span> <a name="line-257"></a> <a name="line-258"></a> <span class='hs-comment'>-- | Plural variant of 'random', producing an infinite list of</span> <a name="line-259"></a> <span class='hs-comment'>-- random values instead of returning a new generator.</span> <a name="line-260"></a> <span class='hs-varid'>randoms</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=></span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <a name="line-261"></a> <span class='hs-varid'>randoms</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-layout'>,</span><span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>x</span> <span class='hs-conop'>:</span> <span class='hs-varid'>randoms</span> <span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>random</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-262"></a> <a name="line-263"></a> <span class='hs-comment'>-- | A variant of 'randomR' that uses the global random number generator</span> <a name="line-264"></a> <span class='hs-comment'>-- (see "System.Random#globalrng").</span> <a name="line-265"></a> <span class='hs-varid'>randomRIO</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span> <a name="line-266"></a> <span class='hs-varid'>randomRIO</span> <span class='hs-varid'>range</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getStdRandom</span> <span class='hs-layout'>(</span><span class='hs-varid'>randomR</span> <span class='hs-varid'>range</span><span class='hs-layout'>)</span> <a name="line-267"></a> <a name="line-268"></a> <span class='hs-comment'>-- | A variant of 'random' that uses the global random number generator</span> <a name="line-269"></a> <span class='hs-comment'>-- (see "System.Random#globalrng").</span> <a name="line-270"></a> <span class='hs-varid'>randomIO</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span> <a name="line-271"></a> <span class='hs-varid'>randomIO</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getStdRandom</span> <span class='hs-varid'>random</span> <a name="line-272"></a> <a name="line-273"></a> <a name="line-274"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Random</span> <span class='hs-conid'>Int</span> <span class='hs-keyword'>where</span> <a name="line-275"></a> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomIvalInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>toInteger</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>toInteger</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <a name="line-276"></a> <span class='hs-varid'>random</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>minBound</span><span class='hs-layout'>,</span><span class='hs-varid'>maxBound</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <a name="line-277"></a> <a name="line-278"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Random</span> <span class='hs-conid'>Char</span> <span class='hs-keyword'>where</span> <a name="line-279"></a> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <a name="line-280"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>randomIvalInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>ord</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>ord</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <a name="line-281"></a> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-layout'>,</span><span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>chr</span> <span class='hs-varid'>x</span><span class='hs-layout'>,</span> <span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <a name="line-282"></a> <span class='hs-varid'>random</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>minBound</span><span class='hs-layout'>,</span><span class='hs-varid'>maxBound</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <a name="line-283"></a> <a name="line-284"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Random</span> <span class='hs-conid'>Bool</span> <span class='hs-keyword'>where</span> <a name="line-285"></a> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <a name="line-286"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>randomIvalInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>bool2Int</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>bool2Int</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <a name="line-287"></a> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-layout'>,</span> <span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>int2Bool</span> <span class='hs-varid'>x</span><span class='hs-layout'>,</span> <span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <a name="line-288"></a> <span class='hs-keyword'>where</span> <a name="line-289"></a> <span class='hs-varid'>bool2Int</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Integer</span> <a name="line-290"></a> <span class='hs-varid'>bool2Int</span> <span class='hs-conid'>False</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span> <a name="line-291"></a> <span class='hs-varid'>bool2Int</span> <span class='hs-conid'>True</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <a name="line-292"></a> <a name="line-293"></a> <span class='hs-varid'>int2Bool</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bool</span> <a name="line-294"></a> <span class='hs-varid'>int2Bool</span> <span class='hs-num'>0</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span> <a name="line-295"></a> <span class='hs-varid'>int2Bool</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span> <a name="line-296"></a> <a name="line-297"></a> <span class='hs-varid'>random</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>minBound</span><span class='hs-layout'>,</span><span class='hs-varid'>maxBound</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <a name="line-298"></a> <a name="line-299"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Random</span> <span class='hs-conid'>Integer</span> <span class='hs-keyword'>where</span> <a name="line-300"></a> <span class='hs-varid'>randomR</span> <span class='hs-varid'>ival</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomIvalInteger</span> <span class='hs-varid'>ival</span> <span class='hs-varid'>g</span> <a name="line-301"></a> <span class='hs-varid'>random</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>minBound</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Int</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>maxBound</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Int</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <a name="line-302"></a> <a name="line-303"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Random</span> <span class='hs-conid'>Double</span> <span class='hs-keyword'>where</span> <a name="line-304"></a> <span class='hs-varid'>randomR</span> <span class='hs-varid'>ival</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomIvalDouble</span> <span class='hs-varid'>ival</span> <span class='hs-varid'>id</span> <span class='hs-varid'>g</span> <a name="line-305"></a> <span class='hs-varid'>random</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Double</span><span class='hs-layout'>,</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <a name="line-306"></a> <a name="line-307"></a><span class='hs-comment'>-- hah, so you thought you were saving cycles by using Float?</span> <a name="line-308"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Random</span> <span class='hs-conid'>Float</span> <span class='hs-keyword'>where</span> <a name="line-309"></a> <span class='hs-varid'>random</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomIvalDouble</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Double</span><span class='hs-layout'>,</span><span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-varid'>realToFrac</span> <span class='hs-varid'>g</span> <a name="line-310"></a> <span class='hs-varid'>randomR</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomIvalDouble</span> <span class='hs-layout'>(</span><span class='hs-varid'>realToFrac</span> <span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>realToFrac</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>realToFrac</span> <span class='hs-varid'>g</span> <a name="line-311"></a> <a name="line-312"></a><a name="mkStdRNG"></a><span class='hs-definition'>mkStdRNG</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>StdGen</span> <a name="line-313"></a><span class='hs-definition'>mkStdRNG</span> <span class='hs-varid'>o</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <a name="line-314"></a> <span class='hs-varid'>ct</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>getCPUTime</span> <a name="line-315"></a> <span class='hs-layout'>(</span><span class='hs-varid'>sec</span><span class='hs-layout'>,</span> <span class='hs-varid'>psec</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>getTime</span> <a name="line-316"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>createStdGen</span> <span class='hs-layout'>(</span><span class='hs-varid'>sec</span> <span class='hs-varop'>*</span> <span class='hs-num'>12345</span> <span class='hs-varop'>+</span> <span class='hs-varid'>psec</span> <span class='hs-varop'>+</span> <span class='hs-varid'>ct</span> <span class='hs-varop'>+</span> <span class='hs-varid'>o</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-317"></a> <a name="line-318"></a><a name="randomIvalInteger"></a><span class='hs-definition'>randomIvalInteger</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span><span class='hs-layout'>,</span> <span class='hs-conid'>Num</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-layout'>(</span><span class='hs-conid'>Integer</span><span class='hs-layout'>,</span> <span class='hs-conid'>Integer</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-319"></a><span class='hs-definition'>randomIvalInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span><span class='hs-varid'>h</span><span class='hs-layout'>)</span> <span class='hs-varid'>rng</span> <a name="line-320"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>l</span> <span class='hs-varop'>></span> <span class='hs-varid'>h</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomIvalInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>h</span><span class='hs-layout'>,</span><span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-varid'>rng</span> <a name="line-321"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>f</span> <span class='hs-varid'>n</span> <span class='hs-num'>1</span> <span class='hs-varid'>rng</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>(</span><span class='hs-varid'>v</span><span class='hs-layout'>,</span> <span class='hs-varid'>rng'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>fromInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span> <span class='hs-varop'>+</span> <span class='hs-varid'>v</span> <span class='hs-varop'>`mod`</span> <span class='hs-varid'>k</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>rng'</span><span class='hs-layout'>)</span> <a name="line-322"></a> <span class='hs-keyword'>where</span> <a name="line-323"></a> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>h</span> <span class='hs-comment'>-</span> <span class='hs-varid'>l</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span> <a name="line-324"></a> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>2147483561</span> <a name="line-325"></a> <span class='hs-varid'>n</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>iLogBase</span> <span class='hs-varid'>b</span> <span class='hs-varid'>k</span> <a name="line-326"></a> <a name="line-327"></a> <span class='hs-varid'>f</span> <span class='hs-num'>0</span> <span class='hs-varid'>acc</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>acc</span><span class='hs-layout'>,</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-328"></a> <span class='hs-varid'>f</span> <span class='hs-varid'>n'</span> <span class='hs-varid'>acc</span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>=</span> <a name="line-329"></a> <span class='hs-keyword'>let</span> <a name="line-330"></a> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-layout'>,</span><span class='hs-varid'>g'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>next</span> <span class='hs-varid'>g</span> <a name="line-331"></a> <span class='hs-keyword'>in</span> <a name="line-332"></a> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-varid'>n'</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>x</span> <span class='hs-varop'>+</span> <span class='hs-varid'>acc</span> <span class='hs-varop'>*</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>g'</span> <a name="line-333"></a> <a name="line-334"></a><a name="randomIvalDouble"></a><span class='hs-definition'>randomIvalDouble</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>RandomGen</span> <span class='hs-varid'>g</span><span class='hs-layout'>,</span> <span class='hs-conid'>Fractional</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=></span> <span class='hs-layout'>(</span><span class='hs-conid'>Double</span><span class='hs-layout'>,</span> <span class='hs-conid'>Double</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Double</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>g</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>g</span><span class='hs-layout'>)</span> <a name="line-335"></a><span class='hs-definition'>randomIvalDouble</span> <span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-layout'>,</span><span class='hs-varid'>h</span><span class='hs-layout'>)</span> <span class='hs-varid'>fromDouble</span> <span class='hs-varid'>rng</span> <a name="line-336"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>l</span> <span class='hs-varop'>></span> <span class='hs-varid'>h</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>randomIvalDouble</span> <span class='hs-layout'>(</span><span class='hs-varid'>h</span><span class='hs-layout'>,</span><span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-varid'>fromDouble</span> <span class='hs-varid'>rng</span> <a name="line-337"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <a name="line-338"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>randomIvalInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>minBound</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Int32</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>maxBound</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Int32</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>rng</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <a name="line-339"></a> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-layout'>,</span> <span class='hs-varid'>rng'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-340"></a> <span class='hs-keyword'>let</span> <a name="line-341"></a> <span class='hs-varid'>scaled_x</span> <span class='hs-keyglyph'>=</span> <a name="line-342"></a> <span class='hs-varid'>fromDouble</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>l</span><span class='hs-varop'>+</span><span class='hs-varid'>h</span><span class='hs-layout'>)</span><span class='hs-varop'>/</span><span class='hs-num'>2</span><span class='hs-layout'>)</span> <span class='hs-varop'>+</span> <a name="line-343"></a> <span class='hs-varid'>fromDouble</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-varid'>h</span><span class='hs-comment'>-</span><span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-varop'>/</span> <span class='hs-varid'>realToFrac</span> <span class='hs-varid'>int32Count</span><span class='hs-layout'>)</span> <span class='hs-varop'>*</span> <a name="line-344"></a> <span class='hs-varid'>fromIntegral</span> <span class='hs-layout'>(</span><span class='hs-varid'>x</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Int32</span><span class='hs-layout'>)</span> <a name="line-345"></a> <span class='hs-keyword'>in</span> <a name="line-346"></a> <span class='hs-layout'>(</span><span class='hs-varid'>scaled_x</span><span class='hs-layout'>,</span> <span class='hs-varid'>rng'</span><span class='hs-layout'>)</span> <a name="line-347"></a> <a name="line-348"></a><a name="int32Count"></a><span class='hs-definition'>int32Count</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span> <a name="line-349"></a><span class='hs-definition'>int32Count</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>maxBound</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Int32</span><span class='hs-layout'>)</span> <span class='hs-comment'>-</span> <span class='hs-varid'>toInteger</span> <span class='hs-layout'>(</span><span class='hs-varid'>minBound</span><span class='hs-keyglyph'>::</span><span class='hs-conid'>Int32</span><span class='hs-layout'>)</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span> <a name="line-350"></a> <a name="line-351"></a><a name="iLogBase"></a><span class='hs-definition'>iLogBase</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Integer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Integer</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Integer</span> <a name="line-352"></a><span class='hs-definition'>iLogBase</span> <span class='hs-varid'>b</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>i</span> <span class='hs-varop'><</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>then</span> <span class='hs-num'>1</span> <span class='hs-keyword'>else</span> <span class='hs-num'>1</span> <span class='hs-varop'>+</span> <span class='hs-varid'>iLogBase</span> <span class='hs-varid'>b</span> <span class='hs-layout'>(</span><span class='hs-varid'>i</span> <span class='hs-varop'>`div`</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <a name="line-353"></a> <a name="line-354"></a><a name="stdRange"></a><span class='hs-definition'>stdRange</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span><span class='hs-conid'>Int</span><span class='hs-layout'>)</span> <a name="line-355"></a><span class='hs-definition'>stdRange</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>,</span> <span class='hs-num'>2147483562</span><span class='hs-layout'>)</span> <a name="line-356"></a> <a name="line-357"></a><a name="stdNext"></a><span class='hs-definition'>stdNext</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StdGen</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>StdGen</span><span class='hs-layout'>)</span> <a name="line-358"></a><span class='hs-comment'>-- Returns values in the range stdRange</span> <a name="line-359"></a><span class='hs-definition'>stdNext</span> <span class='hs-layout'>(</span><span class='hs-conid'>StdGen</span> <span class='hs-varid'>s1</span> <span class='hs-varid'>s2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>fromIntegral</span> <span class='hs-varid'>z'</span><span class='hs-layout'>,</span> <span class='hs-conid'>StdGen</span> <span class='hs-varid'>s1''</span> <span class='hs-varid'>s2''</span><span class='hs-layout'>)</span> <a name="line-360"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>z'</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>z</span> <span class='hs-varop'><</span> <span class='hs-num'>1</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>z</span> <span class='hs-varop'>+</span> <span class='hs-num'>2147483562</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>z</span> <a name="line-361"></a> <span class='hs-varid'>z</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s1''</span> <span class='hs-comment'>-</span> <span class='hs-varid'>s2''</span> <a name="line-362"></a> <a name="line-363"></a> <span class='hs-varid'>k</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s1</span> <span class='hs-varop'>`quot`</span> <span class='hs-num'>53668</span> <a name="line-364"></a> <span class='hs-varid'>s1'</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>40014</span> <span class='hs-varop'>*</span> <span class='hs-layout'>(</span><span class='hs-varid'>s1</span> <span class='hs-comment'>-</span> <span class='hs-varid'>k</span> <span class='hs-varop'>*</span> <span class='hs-num'>53668</span><span class='hs-layout'>)</span> <span class='hs-comment'>-</span> <span class='hs-varid'>k</span> <span class='hs-varop'>*</span> <span class='hs-num'>12211</span> <a name="line-365"></a> <span class='hs-varid'>s1''</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>s1'</span> <span class='hs-varop'><</span> <span class='hs-num'>0</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>s1'</span> <span class='hs-varop'>+</span> <span class='hs-num'>2147483563</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>s1'</span> <a name="line-366"></a> <a name="line-367"></a> <span class='hs-varid'>k'</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s2</span> <span class='hs-varop'>`quot`</span> <span class='hs-num'>52774</span> <a name="line-368"></a> <span class='hs-varid'>s2'</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>40692</span> <span class='hs-varop'>*</span> <span class='hs-layout'>(</span><span class='hs-varid'>s2</span> <span class='hs-comment'>-</span> <span class='hs-varid'>k'</span> <span class='hs-varop'>*</span> <span class='hs-num'>52774</span><span class='hs-layout'>)</span> <span class='hs-comment'>-</span> <span class='hs-varid'>k'</span> <span class='hs-varop'>*</span> <span class='hs-num'>3791</span> <a name="line-369"></a> <span class='hs-varid'>s2''</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>s2'</span> <span class='hs-varop'><</span> <span class='hs-num'>0</span> <span class='hs-keyword'>then</span> <span class='hs-varid'>s2'</span> <span class='hs-varop'>+</span> <span class='hs-num'>2147483399</span> <span class='hs-keyword'>else</span> <span class='hs-varid'>s2'</span> <a name="line-370"></a> <a name="line-371"></a><a name="stdSplit"></a><span class='hs-definition'>stdSplit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StdGen</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>StdGen</span><span class='hs-layout'>,</span> <span class='hs-conid'>StdGen</span><span class='hs-layout'>)</span> <a name="line-372"></a><span class='hs-definition'>stdSplit</span> <span class='hs-varid'>std</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>StdGen</span> <span class='hs-varid'>s1</span> <span class='hs-varid'>s2</span><span class='hs-layout'>)</span> <a name="line-373"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>left</span><span class='hs-layout'>,</span> <span class='hs-varid'>right</span><span class='hs-layout'>)</span> <a name="line-374"></a> <span class='hs-keyword'>where</span> <a name="line-375"></a> <span class='hs-comment'>-- no statistical foundation for this!</span> <a name="line-376"></a> <span class='hs-varid'>left</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StdGen</span> <span class='hs-varid'>new_s1</span> <span class='hs-varid'>t2</span> <a name="line-377"></a> <span class='hs-varid'>right</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StdGen</span> <span class='hs-varid'>t1</span> <span class='hs-varid'>new_s2</span> <a name="line-378"></a> <a name="line-379"></a> <span class='hs-varid'>new_s1</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>s1</span> <span class='hs-varop'>==</span> <span class='hs-num'>2147483562</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>1</span> <a name="line-380"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s1</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span> <a name="line-381"></a> <a name="line-382"></a> <span class='hs-varid'>new_s2</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>s2</span> <span class='hs-varop'>==</span> <span class='hs-num'>1</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>2147483398</span> <a name="line-383"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>s2</span> <span class='hs-comment'>-</span> <span class='hs-num'>1</span> <a name="line-384"></a> <a name="line-385"></a> <span class='hs-conid'>StdGen</span> <span class='hs-varid'>t1</span> <span class='hs-varid'>t2</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>snd</span> <span class='hs-layout'>(</span><span class='hs-varid'>next</span> <span class='hs-varid'>std</span><span class='hs-layout'>)</span> <a name="line-386"></a> <a name="line-387"></a><span class='hs-comment'>-- The global random number generator</span> <a name="line-388"></a> <a name="line-389"></a><span class='hs-comment'>{- $globalrng #globalrng# <a name="line-390"></a> <a name="line-391"></a>There is a single, implicit, global random number generator of type <a name="line-392"></a>'StdGen', held in some global variable maintained by the 'IO' monad. It is <a name="line-393"></a>initialised automatically in some system-dependent fashion, for example, by <a name="line-394"></a>using the time of day, or Linux's kernel random number generator. To get <a name="line-395"></a>deterministic behaviour, use 'setStdGen'. <a name="line-396"></a>-}</span> <a name="line-397"></a> <a name="line-398"></a><a name="setStdGen"></a><span class='hs-comment'>-- |Sets the global random number generator.</span> <a name="line-399"></a><span class='hs-definition'>setStdGen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StdGen</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-conid'>()</span> <a name="line-400"></a><span class='hs-definition'>setStdGen</span> <span class='hs-varid'>sgen</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>writeIORef</span> <span class='hs-varid'>theStdGen</span> <span class='hs-varid'>sgen</span> <a name="line-401"></a> <a name="line-402"></a><a name="getStdGen"></a><span class='hs-comment'>-- |Gets the global random number generator.</span> <a name="line-403"></a><span class='hs-definition'>getStdGen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>StdGen</span> <a name="line-404"></a><span class='hs-definition'>getStdGen</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>readIORef</span> <span class='hs-varid'>theStdGen</span> <a name="line-405"></a> <a name="line-406"></a><a name="theStdGen"></a><span class='hs-definition'>theStdGen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IORef</span> <span class='hs-conid'>StdGen</span> <a name="line-407"></a><span class='hs-definition'>theStdGen</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unsafePerformIO</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span> <a name="line-408"></a> <span class='hs-varid'>rng</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>mkStdRNG</span> <span class='hs-num'>0</span> <a name="line-409"></a> <span class='hs-varid'>newIORef</span> <span class='hs-varid'>rng</span> <a name="line-410"></a> <a name="line-411"></a><a name="newStdGen"></a><span class='hs-comment'>-- |Applies 'split' to the current global random generator,</span> <a name="line-412"></a><span class='hs-comment'>-- updates it with one of the results, and returns the other.</span> <a name="line-413"></a><span class='hs-definition'>newStdGen</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>IO</span> <span class='hs-conid'>StdGen</span> <a name="line-414"></a><span class='hs-definition'>newStdGen</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>atomicModifyIORef</span> <span class='hs-varid'>theStdGen</span> <span class='hs-varid'>split</span> <a name="line-415"></a> <a name="line-416"></a><span class='hs-comment'>{- |Uses the supplied function to get a value from the current global <a name="line-417"></a>random generator, and updates the global generator with the new generator <a name="line-418"></a>returned by the function. For example, @rollDice@ gets a random integer <a name="line-419"></a>between 1 and 6: <a name="line-420"></a> <a name="line-421"></a>> rollDice :: IO Int <a name="line-422"></a>> rollDice = getStdRandom (randomR (1,6)) <a name="line-423"></a> <a name="line-424"></a>-}</span> <a name="line-425"></a> <a name="line-426"></a><a name="getStdRandom"></a><span class='hs-definition'>getStdRandom</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>StdGen</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span><span class='hs-conid'>StdGen</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-varid'>a</span> <a name="line-427"></a><span class='hs-definition'>getStdRandom</span> <span class='hs-varid'>f</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>atomicModifyIORef</span> <span class='hs-varid'>theStdGen</span> <span class='hs-layout'>(</span><span class='hs-varid'>swap</span> <span class='hs-varop'>.</span> <span class='hs-varid'>f</span><span class='hs-layout'>)</span> <a name="line-428"></a> <span class='hs-keyword'>where</span> <span class='hs-varid'>swap</span> <span class='hs-layout'>(</span><span class='hs-varid'>v</span><span class='hs-layout'>,</span><span class='hs-varid'>g</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>g</span><span class='hs-layout'>,</span><span class='hs-varid'>v</span><span class='hs-layout'>)</span> <a name="line-429"></a> <a name="line-430"></a><span class='hs-comment'>{- $references <a name="line-431"></a> <a name="line-432"></a>1. FW #Burton# Burton and RL Page, /Distributed random number generation/, <a name="line-433"></a>Journal of Functional Programming, 2(2):203-212, April 1992. <a name="line-434"></a> <a name="line-435"></a>2. SK #Park# Park, and KW Miller, /Random number generators - <a name="line-436"></a>good ones are hard to find/, Comm ACM 31(10), Oct 1988, pp1192-1201. <a name="line-437"></a> <a name="line-438"></a>3. DG #Carta# Carta, /Two fast implementations of the minimal standard <a name="line-439"></a>random number generator/, Comm ACM, 33(1), Jan 1990, pp87-88. <a name="line-440"></a> <a name="line-441"></a>4. P #Hellekalek# Hellekalek, /Don\'t trust parallel Monte Carlo/, <a name="line-442"></a>Department of Mathematics, University of Salzburg, <a name="line-443"></a><<a href="http://random.mat.sbg.ac.at/~peter/pads98.ps">http://random.mat.sbg.ac.at/~peter/pads98.ps</a>>, 1998. <a name="line-444"></a> <a name="line-445"></a>5. Pierre #LEcuyer# L'Ecuyer, /Efficient and portable combined random <a name="line-446"></a>number generators/, Comm ACM, 31(6), Jun 1988, pp742-749. <a name="line-447"></a> <a name="line-448"></a>The Web site <<a href="http://random.mat.sbg.ac.at/">http://random.mat.sbg.ac.at/</a>> is a great source of information. <a name="line-449"></a> <a name="line-450"></a>-}</span> </pre></body> </html>