我正在尝试定义一个幂函数来计算x ^ y。
let rec powFunA (x,y) =
match (x,y) with
| (_,0) -> 1
| (x,y) -> x * powFunA (x,y-1);;
和
let rec powFunB x y =
match y with
| 0 -> 1
| y -> x * powFunB x y-1;;
呼叫powFunA (2,5)
可以正常工作,并且得到预期的结果是32。但是不知何故,我不明白为什么,第二个呼叫powFunB 2 5
会导致一个StackOverflowException
。
我还遇到了一个定义:
let rec power = function
| (_,0) -> 1.0 (* 1 *)
| (x,n) -> x * power(x,n-1) (* 2 *)
能否请您在定义的第一行说明参数的缺失以及 function 的用法。
谢谢。
答案 0 :(得分:4)
此堆栈溢出错误与F#的优先级规则有关。考虑以下表达式:
powFunB x y-1
此表达式具有一些功能应用程序和减号运算符。在F#中(与所有ML语言一样),函数应用程序具有最高的优先级。没有什么比绑定更具约束力了。
因此,编译器将上述表达式理解为:
(powFunB x y) - 1
也就是说,函数应用程序powFunB x y
首先,减去运算符。现在,我希望很容易看出为什么会导致无限递归。
要解决此问题,只需应用括号即可覆盖优先级规则:
powFunB x (y-1)
“无参数”定义使用F#语法定义多案例函数。这只是允许写= function
而不是x = match x with
的快捷方式。因此,例如,以下两个功能是等效的:
let f a = match a with | Some x -> [x] | None -> []
let g = function | Some x -> [x] | None -> []
就是一些语法糖,仅此而已。因此,您发现的定义与第一个代码段完全相同。