Ocaml“in”关键字和用法

时间:2013-10-27 20:02:03

标签: function functional-programming ocaml

我正在读一些笔记,并且遇到了这段代码,对我来说看起来很干净:

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

1 个答案:

答案 0 :(得分:8)

let 绑定 in body ;您的inlet 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是累积的部分金额。