Ocaml"in"关键字和用法

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).

Bas*_*tch 8

它是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是一个累积的部分和.