[MLton-commit] r5037

Vesa Karvonen vesak at mlton.org
Fri Jan 12 04:29:19 PST 2007


Initial commit of a lib of misc utils to be refactored.
----------------------------------------------------------------------

A   mltonlib/trunk/com/ssh/misc-util/unstable/mk-random-gen.fun

----------------------------------------------------------------------

Added: mltonlib/trunk/com/ssh/misc-util/unstable/mk-random-gen.fun
===================================================================
--- mltonlib/trunk/com/ssh/misc-util/unstable/mk-random-gen.fun	2007-01-12 12:28:55 UTC (rev 5036)
+++ mltonlib/trunk/com/ssh/misc-util/unstable/mk-random-gen.fun	2007-01-12 12:29:12 UTC (rev 5037)
@@ -0,0 +1,94 @@
+(* Copyright (C) 2007 SSH Communications Security, Helsinki, Finland
+ *
+ * This code is released under the MLton license, a BSD-style license.
+ * See the LICENSE file or http://mlton.org/License for details.
+ *)
+
+(*
+ * A functor for making random value generator combinators from a module
+ * providing a random number generator.
+ *)
+
+functor MkRandomGen (RNG : RNG) :>
+   RANDOM_GEN
+      where type t = RNG.t = struct
+   structure D = MkDbg (open DbgDefs val name = "MkRandomGen")
+         and A = Array and R = Real and V = Vector and W = Word
+
+   open RNG
+   type 'a gen = Int.t -> t -> 'a
+
+   val lift = const
+   fun return a _ _ = a
+   fun (m >>= k) n r = k (m n (split 0w314 r)) n (split 0w159 r)
+   fun prj gb b2a n = b2a o gb n
+   fun promote a2b n r a = a2b a n r
+   fun sized i2g n r = i2g n n r
+   fun resize f g = g o f
+   fun bool _ r = maxValue div 0w2 < value r
+
+   fun inRange bInRange (a2b, b2a) =
+       flip prj b2a o bInRange o Pair.map (Sq.mk a2b)
+
+   fun wordInRange (l, h) =
+       (D.assert 0 (fn () => l <= h)
+      ; let val n = h - l + 0w1     (* XXX may overflow *)
+            val d = maxValue div n  (* XXX may result in zero *)
+            val m = n * d
+        in lift (fn r => value r mod m div d + l)
+        end)
+
+   fun intInRange (l, h) =
+       (D.assert 0 (fn () => l <= h)
+      ; prj (inRange wordInRange (Iso.swap W.isoInt) (0, h - l))
+            (op + /> l))
+
+   local
+      val w2r = R.fromLargeInt o W.toLargeInt
+   in
+      fun realInRange (l, h) =
+          (D.assert 0 (fn () => l <= h)
+         ; let val m = (h - l) / w2r maxValue
+           in const (fn r => w2r (value r) * m + l)
+           end)
+   end
+
+   fun elements xs =
+       let val xs = V.fromList xs
+       in prj (intInRange (0, V.length xs)) (xs <\ V.sub)
+       end
+
+   fun oneOf gs = elements gs >>= id
+
+   fun frequency xs = let
+      val xs = A.fromList xs
+      val tot = A.foldli (fn (i, (n, g), tot) =>
+                             (A.update (xs, i, (n+tot, g)) ; n+tot))
+                         0 xs
+      fun pick i n = let
+         val (k, x) = A.sub (xs, i)
+      in
+         if n <= k then x else pick (i+1) n
+      end
+   in
+      intInRange (1, tot) >>= pick 0
+   end
+
+   local
+      fun unfold px sx x2y = let
+         fun lp ys x =
+             if px x then
+                rev ys
+             else
+                lp (x2y x::ys) (sx x)
+      in
+         lp []
+      end
+   in
+      fun list ga m n r =
+          unfold (op = /> 0w0)
+                 (op - /> 0w1)
+                 (ga n o flip split r)
+                 (W.fromInt m)
+   end
+end


Property changes on: mltonlib/trunk/com/ssh/misc-util/unstable/mk-random-gen.fun
___________________________________________________________________
Name: svn:eol-style
   + native




More information about the MLton-commit mailing list