Syntax 此表达式的类型为int,但此处与类型unit一起使用

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

我试图在F#中获得与此vb.net代码完全等效的代码(不是函数):

函数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))