将两个数字乘以 F# 中的连续总和

Multiplying two numbers by successive sums in F#

将 m 和 n 作为整数,我可以将它们乘以连续的总和,如下所示:

    m * n = m + m + m + ... + m (n times) 

所以,让我们考虑下面的伪代码:

    m = ... (first number)
    n = ... (second number)

    Result = 0;
    while (n > 0)
    {
        Result = Result + m;
        n = n - 1;
    }

在知道变量不可变的情况下如何在 F# 中实现此算法? 换句话说,如何在连续迭代中更新变量 Resultn

有人可以用 F# 编写这个算法吗?

谢谢

脚注:我开始学习 F#,我对函数式编程感到很困惑。

首先,你可以在F#中使用可变变量,所以你的算法可以这样写:

let multiply1 m n =
    let mutable result = 0
    for i = 1 to n do
        result <- result + m
    result

但是如果你想以更实用的方式来做,你可以使用递归。在这种情况下,一个累加结果的内部函数:

let multiply2 m n =
    let rec loop x acc =
        if x = 0 then acc
        else loop (x - 1) (acc + m)
    loop n 0

multiply2 函数使用一个称为 loop 的内部递归函数,它在 acc 参数中累积乘法结果。所以循环调用自己 n 次并每次将 m 添加到累加器。一旦 x 达到零,将返回此结果。

从技术上讲,您也可以编写不带累加器参数的代码:

let multiply3 m n =
    let rec loop x =
        if x = 0 then 0
        else m + loop (x - 1)
    loop n

也许这段代码对于初学者来说更容易理解,但应该避免使用,因为它不使用 tail recursion 并且这会导致问题。例如,这将导致 WhosebugException:

multiply3 5 1000000 // This will cause a WhosebugException.
|> printfn "Result: %d"

您可以使用 Seq(像 haskell 中的惰性列表/像 C# 中的 IEnumerable)和管道运算符:

let mult n (m:int) =
    Seq.initInfinite (fun _ -> m)
    |> Seq.take n
    |> Seq.sum