2012-12-04 62 views
1

我知道let rec用于我想要的recursive什么时候我们使用let rec?

例如,

let rec power i x = if i = 0 then 1.0 else x *. (power (i-1) x);;

好吧,我理解这一点。


但是这个怎么样:

let x y = y + y in x 2

我应该在里面用rec吗?

我想我应该,因为它里面有x 2,加载本身,但它似乎与编译器很好。

那么当我应该使用let rec而不应该?


另外,就是

let (-) x y = y - x in 1-2-3;;

let rec (-) x y = y - x in 1-2-3;;

的区别他们是否合法?

回答

7

您需要先了解OCaml的范围规则。

当你写let f XXX = YYY in ZZZ,如果你使用fYYY那么你需要rec。在两种情况下(即有或没有rec),f将在ZZZ中定义。

所以:

let x y = y + y in 
x 2 

是完全有效的。

对于你第二个问题:不,它不是等价的,如果你在顶层尝试它,第二个语句永远循环,相当于let rec loop x y = loop y x in()。为了理解它为什么会一直循环,您可以理解loop的应用作为标识符被其主体替换的扩展。所以:

所以loop身体function x y -> loop y x,可扩展到 function x y -> (function a b -> loop b a) y x(我已经改名为参数名,以避免歧义),当你申请的身体等等等等这相当于function x y -> loop x y。所以这个函数永远不会做任何事情,它只是试图扩展/应用它的身体并交换它的参数而永远循环。

+0

你能解释一下为什么'让rec( - )x y = y - x in 1-2-3 ;;'会永远循环吗? –

+0

@JacksonTale:你正在定义函数'-',然后在函数体'x-y'内使用它。所以,'x-y'再次被扩展(有点)到'x-y'中......然后...... –

+0

@AsiriRathnayake你的意思是我** rec ** define **( - )**,然后** yx **将变成** xy **然后** yx **然后** xy ** .....不停止? –

相关问题