Emm*_*uel 3 ocaml functional-programming function
我正在读一些笔记,并且遇到了这段代码,对我来说看起来很干净:
# 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.
Run Code Online (Sandbox Code Playgroud)
我理解除了那里的部分以外的每一点in sum(0, 0.0).那么问题实际上并不是in关键字,而是:sum(0, 0.0).这是什么意思,为什么这个功能有用呢?我做了一些谷歌搜索,并in从Ocaml网站上获得了关键字,但这对我没有意义.这是我发现的:
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
Run Code Online (Sandbox Code Playgroud)
我不需要解释实际功能.我需要帮助的是那么小in sum(0, 0.0).
它是let 绑定 in 身体 ; 你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);;
Run Code Online (Sandbox Code Playgroud)
是一个内部尾递归函数来做一个循环,sum(0,0.0)(带有那个内部sum定义)的结果是sigma函数的结果.
这sum(0,0.0)是尾递归的起点.
我建议你使用Ocaml的调试器,或者至少添加一个
Printf.printf "sum i=%d z=%f\n";
Run Code Online (Sandbox Code Playgroud)
线后排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;;
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我会循环减少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 ;;
Run Code Online (Sandbox Code Playgroud)
我同意我的sigma功能略有不同(特别是如果参数f是带有副作用的不纯函数).我命名了内部尾递归函数sumloop(不仅仅是sum)来强调它是一个循环.
你的z正式sum和我的s正式sumloop是一个累积的部分和.