将两个数字乘以 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# 中实现此算法?
换句话说,如何在连续迭代中更新变量 Result 和 n ?
有人可以用 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
将 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#,我对函数式编程感到很困惑。
首先,你可以在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