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

时间:2015-03-06 10:37:32

标签: f# functional-programming immutability

将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#中实现此算法,知道变量是不可变的? 以另一种方式提出问题,如何在连续迭代中更新变量 Result n

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

谢谢

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

2 个答案:

答案 0 :(得分:2)

首先,您可以在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次,并每次向累加器添加mx达到零后,将返回此结果。

从技术上讲,你也可以在没有accumulator参数的情况下编写代码:

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

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

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

答案 1 :(得分:1)

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

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