Syntax 此表达式的类型为int,但此处与类型unit一起使用
我试图在F#中获得与此vb.net代码完全等效的代码(不是函数):Syntax 此表达式的类型为int,但此处与类型unit一起使用,syntax,f#,Syntax,F#,我试图在F#中获得与此vb.net代码完全等效的代码(不是函数): 函数FastPow(ByVal num作为Double,ByVal exp作为Integer)作为Double 双精度图像分辨率=1 如果exp1时执行此操作 如果exp Mod 2=1,则 res=res*num num=num*num exp=exp>>1 环 返回res*num 端函数 我写道: let FastPow num exp = let mutable ex = exp let mutable re
函数FastPow(ByVal num作为Double,ByVal exp作为Integer)作为Double
双精度图像分辨率=1
如果exp<1,则
如果exp=0,则返回res
exp=-exp
num=1/num
如果结束
在exp>1时执行此操作
如果exp Mod 2=1,则
res=res*num
num=num*num
exp=exp>>1
环
返回res*num
端函数
我写道:
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
让FastPow num exp=
设可变ex=exp
设可变res=1
设可变n=num
如果ex<1,则
如果ex=0,则res
例1
res*n
但是在res的“if ex=0那么res”行中,我得到了一个错误:“此表达式具有int类型,但此处与type unit一起使用”。 我不明白为什么它会给我这个错误。
编辑:我实际上也收到了一个警告:
此表达式的类型应为“unit”,但类型为“int”。
在“if(ex%2=1)then”这意味着
之后应该有一些表达式,但您有整数值。不能从函数的中间跳出
编辑
“如果”不起作用是因为
ex >>> 1
should be
ex <- ex >>> 1
ex>>>1
应该是
ex>>1
下面是有效的代码:
let FastPow num exp =
let calcExp num exp =
let mutable res = 1.0
let mutable n = num
let mutable ex = exp
while ex > 1 do
if ((ex % 2) = 1) then
res <- res * n
n <- n * n
ex <- ex >>> 1
res * n
match exp with
| ex when ex = 0 -> 1.0
| ex when ex < 0 -> calcExp (1.0/num) -exp
| _ -> calcExp num exp
让FastPow num exp=
让calcExp num exp=
设可变res=1.0
设可变n=num
设可变ex=exp
当ex>1时
如果((ex%2)=1),则
决议1
res*n
匹配
|ex=0->1.0时的ex
|ex<0->calcExp(1.0/num)时的ex-exp
|->calcExp num exp
我只是把计算作为一个单独的函数,最后检查参数。问题是如果一个if语句要解析为一个值而不是一个单位,你需要“then”部分和“else”部分,这两个部分解析为同一类型
例如:
let a = if true then 1;;
将生成相同的错误-表达式的类型为int,但与类型unit一起使用
然而:
let a = if true then 1 else 0;;
将计算为int而不会出现错误。这是您能得到的最接近的结果,因为其他人已经说过,您不能跳出函数的中间,并且有一个地方是您不更新变量(在中间)
让FastPow num exp=
设可变exp=exp
设可变res=1
设可变n=num
匹配
|O->n
实验一
如果(exp%2=1),则
决议1
res*n
如果它写得更函数化,我会更漂亮。在F#中,函数的返回值是函数中计算的最后一个表达式。因此,让我们关注以下几点:
if ex < 1 then
if ex = 0 then res (* <--- this is not an early return *)
ex <- -ex (* <--- F# evaluates this code after the *)
n <- 1 / n (* if statement *)
我们仍然有一个bug,尽管我认为F#在错误的地方报告了错误。表达式exp>>>1
返回一个int,它不分配任何变量,因此它与原始C#代码不同。我想您是想使用ex
变量。我们可以按如下方式修复您的代码:
let FastPow2 num exp =
if exp = 0 then 1
else
let mutable ex = exp
let mutable res = 1
let mutable n = num
if ex < 1 then
ex <- -ex
n <- 1 / n
while ex > 1 do
if (ex % 2 = 1) then
res <- res * n
n <- n * n
ex <- ex >>> 1
res * n
让FastPow2 num exp=
如果exp=0,则为1
其他的
设可变ex=exp
设可变res=1
设可变n=num
如果ex<1,则
例1
| _ ->
让rec循环exresn=
如果ex>1,则
设newRes=如果ex%2=1,则res*n否则res
循环(ex>>>1)newRes(n*n)
其他资源*n
设ex,n=如果exp<1,则(-exp,1/num)else(exp,num)
环路ex1n
好多了!还有一些空间可以美化此功能,但你会想到:)谢谢你的回答。这是当前的非功能版本
let FastPow num exp =
let mutable ex = exp
let mutable res = 1.0
let mutable n = num
if ex = 0 then 1.0
else
if ex < 1 then
ex <- -ex
n <- 1.0 / n
while ex > 1 do
if (ex % 2 = 1) then res <- res * n
n <- n * n
ex <- ex >>> 1
res * n
让FastPow num exp=
设可变ex=exp
设可变res=1.0
设可变n=num
如果ex=0,则为1.0
其他的
如果ex<1,则
前任
let FastPow2 num exp =
if exp = 0 then 1
else
let mutable ex = exp
let mutable res = 1
let mutable n = num
if ex < 1 then
ex <- -ex
n <- 1 / n
while ex > 1 do
if (ex % 2 = 1) then (* still have a bug here *)
res <- res * n
n <- n * n
exp >>> 1 (* <--- this is not a variable assignment *)
res * n
let FastPow2 num exp =
if exp = 0 then 1
else
let mutable ex = exp
let mutable res = 1
let mutable n = num
if ex < 1 then
ex <- -ex
n <- 1 / n
while ex > 1 do
if (ex % 2 = 1) then
res <- res * n
n <- n * n
ex <- ex >>> 1
res * n
let FastPow2 num exp =
match exp with
| 0 -> 1
| _ ->
let rec loop ex res n =
if ex > 1 then
let newRes = if ex % 2 = 1 then res * n else res
loop (ex >>> 1) newRes (n * n)
else res * n
let ex, n = if exp < 1 then (-exp, 1 / num) else (exp, num)
loop ex 1 n
let FastPow num exp =
let mutable ex = exp
let mutable res = 1.0
let mutable n = num
if ex = 0 then 1.0
else
if ex < 1 then
ex <- -ex
n <- 1.0 / n
while ex > 1 do
if (ex % 2 = 1) then res <- res * n
n <- n * n
ex <- ex >>> 1
res * n
let rec loop res num exp =
if exp = 0 then res
elif (exp % 2) = 1 then loop (res * num) (num * num) (exp / 2)
else loop res (num * num) (exp / 2)
let FP num exp =
let n = if exp < 0 then 1.0 / num else num
loop 1.0 n (Math.Abs(exp))