【问题标题】:Ocaml "in" keyword and usageOcaml“in”关键字和用法
【发布时间】:2013-11-06 12:28:22
【问题描述】:

我正在阅读一些笔记,发现这段代码对我来说看起来很干净:

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

【问题讨论】:

  • 我对这个问题投了反对票,但回答了这个问题,因为我觉得这个问题很令人困惑,而且任何关于 Ocaml 的教程都比我们在几分钟内能解释得更好。

标签: function functional-programming ocaml


【解决方案1】:

let绑定inbody;你的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)(带有内部sumdefinition)的结果是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;;

顺便说一句,我会循环减少 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 是累积的部分总和。

【讨论】:

  • erm...你没有回答我的问题。为什么是sum(0, 0.0) 而不是sum(4, 5.5)
  • @siaw_23 当某人试图帮助您时,对他们的回答投反对票是一种非常糟糕的形式。您会注意到 Basile 现在已经很好地回答了您的问题。
  • @ChrisTaylor 我没有否决他的回答。我不知道是谁干的。我真的很感谢他的帮助。 :)
  • @siaw_23 我的错;道歉。
猜你喜欢
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 2021-03-14
  • 2022-08-06
  • 1970-01-01
相关资源
最近更新 更多