I have defined three different functions that will perform calculations and return a value. These functions will consistently be redefining a variable until a specific condition is reached. I am having issues getting these to run in a "loop" scenario. I know functional languages are not best for performing loops and you should use recursion...but I am having a hard time wrapping my head around how to perform this.
I will make some real simple arbitrary functions to explain my situation.
fun add_them (a,b) =
a+b;
fun substract_them (c,d) =
c-d;
fun add_them2 (e,f) =
e-f;
val a = 5;
val b = 7;
val c = 10;
val d = 1;
val a = add_them (a,b);
val d = add_them2 (c,d);
So let's say I want to run the last two lines a 1000 times. So Val A and Val D will keep getting added up to a huge number. Now I could literally copy and paste those two lines a 1000 times and get the result I want..but this of course defeats the purpose of programming :)
I was trying to create a loop that I can throw these two functions in. I was coming up with something like below, but I would have no idea how to incorporate these two. Perhaps I am going at this completely backwards.
fun whileloop (x,a) =
if (a<1)
then x
else whileloop(x+1,a-1);
So my goal was to insert those above val a and val d expressions into another function using recursion and run it a certain amount of times. Any help would be much appreciated.
A function that simply iterates another function n times is given in my answer here. But it sounds like you want to apply a given function n times to a seed, like so:
f (f (f (f ... (f x) ... )))
That can be accomplished by the following function:
fun repeat n f x = if n = 0 then x else repeat (n-1) f (f x)
For example,
val n = repeat 20 (fn => n + 1) 0
results in 20.
Or perhaps you want to repeat based on a condition instead of a count:
fun repeatWhile p f x = if p x then repeatWhile p f (f x) else x
For example,
val n = repeatWhile (fn x => x > 0) (fn x => x - 1) 20
returns 0.
Both functions are polymorphic, so also work with tuples. For example:
val (x, y) = repeatWhile (fn (a, b) => a > 0) (fn (a, b) => (a-1, b+1)) (20, 0)
returns (0, 20).
If you dislike using two separate function parameters for condition and "action", you can also combine them by having it return a pair:
fun repeatWhile2 f x =
let val (c, y) = f x in if c then repeatWhile2 f y else x end
Then:
repeatWhile (fn (a, b) => (a > 0, (a-1, b+2))) (20, 0)