在C中,我会用循环解决问题。代表这个想法,例如:
void foo(int x){
while(x > 0){
printf("%d", x % 10);
x /= 10;
}
}
使用F#,我无法使函数返回单个值。我试过了:
let reverse =
let aux =
fun x ->
x % 10
let rec aux2 =
fun x ->
if x = 0 then 0
else aux2(aux(x / 10))
aux2 n
但它始终返回基本案例0
。
我无法超越这种方法,其中递归结果通过操作维护,并且不能单独报告(根据可能的理解):
let reverse2 =
let rec aux =
fun x ->
if x = 0 then 0
else (x % 10) + aux (x / 10) // The operation returning the result
aux n
这是我正在做的一个简单的练习,以便"功能化"我脑海。因此,我正在寻找一种不涉及库函数的方法来解决这个问题。
答案 0 :(得分:6)
更改可变变量值的for循环可以重写为递归函数。您可以将可变变量视为函数的隐式参数。因此,如果我们有一个可变变量x
,我们需要明确地将新状态x
作为函数参数传递。与C函数最接近的等效函数是递归F#函数:
let rec foo x =
if x > 0 then
printf "%d" (x % 10)
foo (x / 10)
这本身并不是特别有用,因为它返回unit
并且只有副作用。您可以使用其他参数收集每个循环的结果。这通常称为累加器:
let foo x =
let rec loop x acc =
if x > 0 then
loop (x / 10) (x % 10 :: acc)
else acc
loop x [] |> List.rev
foo 100 // [0; 0; 1]
我创建了一个内部loop
函数,它实际上是递归函数。外部foo
函数从内部循环开始,[]
作为累加器。在每次迭代期间,项目被添加到列表的开头,并且累加器列表在结束时反转。
您可以使用其他类型作为累加器,例如一个字符串,并附加到字符串而不是将项添加到列表中。