我正在读一些笔记,并且遇到了这段代码,对我来说看起来很干净:
# let sigma f m =
let rec sum (i, z) =
if i = m then z else sum(i+1, z+.f i)
in sum(0, 0.0);;
val sigma : (int -> float) -> int -> float = <fun>
# sigma (function k -> float (k*k)) 10;;
- : float = 285.
我理解除了in sum(0, 0.0)
之外的所有部分。问题实际上并不是in
关键字,而是sum(0, 0.0)
。这是什么意思,为什么这个功能有用呢?我做了一些谷歌搜索,并从Ocaml网站的in
关键字得到了一些东西,但这对我没有意义。这是我发现的:
class-expr ::= class-path
∣ [ typexpr {, typexpr} ] class-path
∣ ( class-expr )
∣ ( class-expr : class-type )
∣ class-expr {argument}+
∣ fun {parameter}+ -> class-expr
∣ let [rec] let-binding {and let-binding} in class-expr
∣ object class-body end
我不需要解释实际功能。我需要帮助的是那个微小的in sum(0, 0.0)
。
答案 0 :(得分:8)
let
绑定 in
body ;您的in
与let rec sum
所以内部
let rec sum (i, z) =
if i = m then z else sum(i+1, z+.f i)
in sum(0, 0.0);;
是用于创建循环的内部尾递归函数,sum(0,0.0)
(具有该内部sum
定义)的结果是sigma
函数的结果。
sum(0,0.0)
是尾递归的起点。
我建议你使用Ocaml的调试器,或者至少添加一个
Printf.printf "sum i=%d z=%f\n";
紧跟在let rec sum(i,z) =
行之后。
let rec sum i z =
if i = m then z else sum(i+1) (z+.f i)
in sum 0 0.0;;
BTW,我会循环减少i
而代码
let sigma f m =
let rec sumloop i s =
(* Printf.printf "sumloop i=%d s=%f\n" i s ; *)
if (i <= 0) then s
else sumloop (i-1) (s+.f i)
in sumloop m 0.0 ;;
我同意我的sigma
函数略有不同(特别是如果参数f
是带有副作用的不纯函数)。我将内部尾递归函数命名为sumloop
(不仅仅是sum
),以强调它是一个循环。
您的z
正式到sum
和我的s
正式到sumloop
是累积的部分金额。