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

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

问题描述

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

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

使用rec关键字标记这个递归函数的原因是什么?



是否确保编译器可以递归?做一定的优化?



如果排除它,会发生什么情况?

解决方案

这可能是有益的:

  let Main()= 
let f(x)=
printfn 原始f:%dx
让f(x)=
//让rec f(x)=
printfn输入新的f:%dx
if x> 0然后
f(x-1)
else
printfndone
f(3)
Main()

打印

 输入新的f:3 
原始f:2

现在,如果我们注释 let 并取消注释让rec ,然后打印

 输入新f:3 
输入新f:2
输入新f:1
输入新f:0
完成

因此,从这个角度来看,这只是名称绑定。 让rec 立即将标识符放在范围内(在本例中,阴影前面的 f ),而<$ c $



该规则的动机源于与类型推断的交互作用。c> let 将标识符置于作用域中。

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)

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?

What happens if you exclude it?

解决方案

This might be instructive:

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()

That prints

entered new f: 3
original f: 2

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

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天全站免登陆