在 F# 中将递归函数标记为 rec 的原因是什么? [英] What's the reason of marking a recursive function as rec in F#?

查看:16
本文介绍了在 F# 中将递归函数标记为 rec 的原因是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定这是否是一个愚蠢的问题,但我正在阅读 VS 2010 附带的教程,并且有这样的功能:

I am not sure if this is a stupid question but I was going through the tutorial that comes with VS 2010 and there is a function like this:

let rec factorial n = if n=0 then 1 else n * factorial (n-1)

这个递归函数要标上rec关键字的原因是什么?

What's the reason of this recursive function to be marked with the rec keyword?

这是为了让编译器确信它是递归的,因此可以进行某些优化吗?

Is it so that the compiler is assured of it being recursive so can do certain optimizations?

如果排除它会怎样?

推荐答案

这可能很有启发性:

let Main() =
    let f(x) = 
        printfn "original f: %d" x
    let f(x) =
    //let rec f(x) =
        printfn "entered new f: %d" x
        if x > 0 then
            f(x-1)
        else
            printfn "done"
    f(3)
Main()

打印出来

entered new f: 3
original f: 2

现在,如果我们注释掉 let 并取消注释 let rec,那么它会打印

Now if we comment out let and uncomment let rec, then it prints

entered new f: 3
entered new f: 2
entered new f: 1
entered new f: 0
done

所以从这个角度来看,它只是关于名称绑定;let rec 立即将标识符放入作用域中(在本例中,隐藏了前面的 f),而 let 仅在其之后才将标识符放入作用域中主体已定义.

So from that point of view, it's just about name binding; let rec puts the identifier in scope immediately (in this example, shadowing the previous f), whereas let puts the identifier in scope only after its body is defined.

该规则的动机确实源于与类型推断的交互.

The motivation for the rule does stem from interactions with type inference.

这篇关于在 F# 中将递归函数标记为 rec 的原因是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆