我正在做一些功课,但我已经被困了好几个小时了。 我确信它真的很微不足道,但在深入了解所有可用的文档后,我仍然无法绕过它。 有人可以帮我一把吗? 基本上,OCaml编程中的练习要求通过平方算法用求幂来定义函数x ^ n。
我看过解决方案:
let rec exp x = function
0 -> 1
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| n when n mod 2 <> 0 -> let y = exp x ((n-1)/2) in y*y*x
;;
我特别不明白的是如何从fun语句中省略参数n以及为什么它应该用作与x匹配的变量,它与通过平方的指数定义没有明显的联系
我将如何做到这一点:
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
答案 0 :(得分:2)
您的版本在语法上是正确的,产生了一个很好的答案,但执行起来很长。
在你的代码中,exp
被递归地调用两次,因此产生两倍的计算,每次调用产生两倍的计算,等等到n=0
。在解决方案中,exp
仅被调用一次,结果存储在变量y
中,然后y
被平方。
现在,关于语法,
let f n = match n with
| 0 -> 0
| foo -> foo-1
相当于:
let f = function
| 0 -> 0
| foo -> foo-1
行let rec exp x = function
是一个函数的求,它接受两个参数:x
,以及模式匹配中使用的未编号参数。在模式匹配中,行
| n when n mod 2 = 0 ->
将此参数命名为n
。并不是在模式匹配的每种情况下都可以使用不同的名称(即使那样不太清楚):
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| p when p mod 2 <> 0 -> let y = exp x ((p-1)/2) in y*y*x
答案 1 :(得分:1)
关键字“function”不是
的语法糖match x with
但是
fun x -> match x with
从而
let rec exp x = function
可以替换为
let rec exp x = fun y -> match y with
当然等同于您的解决方案
let rec exp x y = match y with
请注意,我写了“y”而不是“n”以避免混淆。匹配后引入的n变量是一个新变量,它只与函数参数相关,因为它与之匹配。例如,而不是
let y = x in ...
你可以写:
match x with y -> ...
在此匹配表达式中,“y”表达式是匹配的“模式”。和任何模式一样,它将变量(此处为y)与匹配的值绑定在一起。 (这里是x的值)和任何模式一样,模式中的变量是新变量,可能会影响先前定义的变量。在您的代码中:
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
两个案例中的变量n影响参数n。但这不是问题,因为具有相同名称的两个变量具有相同的值。