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.
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)] *)