功能数字恢复

Wor*_*ice 2 f#

在C中,我将用循环解决问题.为了表达这个想法,例如:

void foo(int x){
    while(x > 0){
        printf("%d", x % 10);
        x /= 10;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

但它总是返回基本情况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
Run Code Online (Sandbox Code Playgroud)

这是我正在做的一个简单的练习,以"功能化"我的思想.因此,我正在寻找一种不涉及库函数的方法.

The*_*Fox 6

更改可变变量值的for循环可以重写为递归函数.您可以将可变变量视为函数的隐式参数.因此,如果我们有一个可变变量x,我们需要将新的x显式状态作为函数参数传递.与递归F#函数最接近的C函数是:

let rec foo x =
    if x > 0 then
        printf "%d" (x % 10)
        foo (x / 10)
Run Code Online (Sandbox Code Playgroud)

这本身并不是特别有用,因为它返回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]
Run Code Online (Sandbox Code Playgroud)

我创建了一个内部loop函数,实际上是递归函数.外部foo函数[]作为累加器从内部循环开始.在每次迭代期间,项目被添加到列表的开头,并且累加器列表在结束时被反转.

您可以使用其他类型作为累加器,例如字符串,并附加到字符串而不是将项添加到列表中.