Home > Back-end >  SML returns the same tuples
SML returns the same tuples

Time:08-26

I'm currently learning Standard ML, just for fun; What I'm trying to do is generate a list of 3-tuples of random ints between 1 and 100. My code:

fun reload() = use "filtertest.sml";

fun getSeed() = 
  LargeInt.toInt(Time.toMicroseconds(Time.now()) mod 1000);

fun fastpower(x, 0) = 1
  | fastpower(x, n) = 
      if n mod 2 = 0 then 
        fastpower(x*x, n div 2)
      else 
        x * fastpower(x*x, n div 2);

fun getRand(seed) = 
  let
    val m = 256
    val a = 11035
    val c = 12345
  in
    (a * seed   c) mod m
  end;

fun getRandTup() = 
  let
    val a = getRand(getSeed())
    val b = getRand(a)
    val c = getRand(b)
  in
    (a, b, c)
  end;

fun sumTup(x: int, y: int, z: int) = x   y   z;

fun getFromLast(lastTup) = 
  let
    val a = getRand(sumTup(lastTup))
    val b = getRand(a)
    val c = getRand(b)
  in
    (a, b, c)
  end;

fun genTupsHelper(0, tupList) = tupList
  | genTupsHelper(n, []) = 
      genTupsHelper(n-1, getRandTup() :: [])
  | genTupsHelper(n, tupList) = 
      getFromLast(hd tupList) :: genTupsHelper(n-1, tupList);

fun genTups(n) =
  genTupsHelper(n, []);

However, when I evaluate

genTups(10) 

My output is:

- genTups(10);
val it =
  [(243,218,55),(243,218,55),(243,218,55),(243,218,55),(243,218,55),
   (243,218,55),(243,218,55),(243,218,55),(243,218,55),(85,48,73)]
  : (int * int * int) list

I don't quite understand what I'm doing wrong here. Any help would be greatly appreciated.

CodePudding user response:

Suggestion: use the Random structure.

val r = Random.rand();

fun getRand(a, b) =
  Random.randRange (a, b) r;

fun getTuple(a, b) =
  (getRand(a, b), getRand(a, b), getRand(a, b));

getTuple(0, 100);
(* (2, 9, 97) *)

Now, let's write a listInit function that creates a list of n length using the results of calling a function.

fun listInit(n, f) =
  let
    fun aux(s, e, f, acc) =
      if s >= e then List.rev acc
      else aux(s 1, e, f, f s :: acc)
  in
    aux(0, n, f, [])
  end;

For instance:

listInit(3, (fn i => i));
(* [0, 1, 2] *)

We could also use this to generate a list of five random tuples.

listInit(5, (fn _ => getTuple(0, 100)));
(* [(10, 26, 31), (94, 46, 38), (7, 46, 89), 
    (92, 75, 61), (14, 60, 88)] *)
  • Related