I’m trying to get the exact equivalent (not functional) of this vb.net code in F#:
Function FastPow(ByVal num As Double, ByVal exp As Integer) As Double Dim res As Double = 1 If exp < 1 Then If exp = 0 Then Return res exp = -exp num = 1 / num End If Do While exp > 1 If exp Mod 2 = 1 Then res = res * num num = num * num exp = exp >> 1 Loop Return res * num End Function
I wrote this:
let FastPow num exp = let mutable ex = exp let mutable res = 1 let mutable n = num if ex < 1 then if ex = 0 then res ex <- -ex n <- 1 / n while ex > 1 do if (ex % 2 = 1) then res <- res * n n <- n * n exp >>> 1 res * n
but in the line ‘if ex = 0 then res’ at res I got an error:
‘This expression has type int but is here used with type unit’. I cannot understand why it gives me that error.
Edit: i actually got a warning as well:
‘This expression should have type ‘unit’, but has type ‘int’.’
at ‘if (ex % 2 = 1) then’
In F#, a function’s return value is the last expression evaluated in the function. So, lets focus on the following:
Additionally, if statements have return values, which also happens to be the last value executed in the if statement. If an if statement isn’t the return value of a function, it should have the return type
unit. Notice that variable assignment has a return type ofunit.We need to rewrite your code to accomodate your early return, so we can do this:
We still have a bug, although I think F# is reporting the error in the wrong place. The expression
exp >>> 1returns an int, it does not assign any variables, so its not equivalent to your original C# code. I think you meant to use theexvariable instead. We can fix your code as follows:Now your function is fixed, but its really really ugly. Lets convert it to more idiomatic F#. You can replace the if statement with pattern matching, and replace the while loop with recursion:
Much better! Theres still some more room to beautify this function, but you get the idea 🙂