Reputation: 37
I am converting a c# recursive function to f#. I am not really familiar with F#. I had a bunch of errors with I dont know why. I did look up the recursive function syntax but with all the if statements I have, I am confused on how to write it in f#.
Here are the c# recursive function
private List<double> ReturnClosestInList(List<double> allKey, int begin, int end)
{
if (end >= begin)
{
int mid = begin + (end - begin) / 2;
if (allKey[mid] > input) return ReturnClosestInList(allKey, begin, mid - 1);
return ReturnClosestInList(allKey, mid + 1, end);
}
if (end < 0) end = begin + 1;
if (begin < 0) begin = end + 1;
if (end > allKey.Count - 1) end = begin - 1;
if (begin > allKey.Count - 1) begin = end - 1;
return new List<double> { allKey[begin], allKey[end] };
}
And here are the f# code that I wrote and the error:
let rec ReturnClosestInList (allKey : List<double>) (start : int) (finish : int) (input : double)=
if(finish >= start) then
let mid = start + (finish - start) / 2
if(allKey.[mid] > input) then
ReturnClosestInList allKey start (mid - 1) input
else ReturnClosestInList allKey (start + 1) mid input
else
if finish < 0 then
finish = start + 1
elif start < 0 then
start = finish + 1
elif finish > allKey.Length - 1 then
finish = start - 1
else start > allKey.Length - 1 then
start = finish - 1
let c : List<double> = [allKey.[start]; allKey.[finish]]
c
Upvotes: 0
Views: 107
Reputation: 243096
There are two issues with your code. The first is that you are treating start
and finish
as mutable values. The other is that your else
branch does not return a value.
To fix the former, I think the best way is to reassign the variable using something like this:
let start, finish =
if finish < 0 then
start, start + 1
elif start < 0 then
finish + 1, finish
elif finish > allKey.Length - 1 then
start, start - 1
elif start > allKey.Length - 1 then
finish - 1, finish
else start, finish
The idea is that you are defining new variables of the same name and you assign them both a new value. As you need to update values of one or the other, the code reassigns both of them (with the else
branch not doing anything special).
The first issue is that both branches of your if
have to return a result. To do this, you need to write something like this:
if(finish >= start) then
let mid = start + (finish - start) / 2
if(allKey.[mid] > input) then
ReturnClosestInList allKey start (mid - 1) input
else ReturnClosestInList allKey (start + 1) mid input
else
let start, finish =
// (all the code to tweak start/finish goes here)
[allKey.[start]; allKey.[finish]]
This way, the return value of the if
case is whatever you get from the recursive call. The return of the other case is whatever you build using [ ... ]
.
It is also worth noting that your code does not look very functional, so if you are learning F#, I'd recommend writing this using pattern matching rather than by converting code from C#. You'll get a much nicer and easier to understand solution.
Upvotes: 1