Ocaml - 全局vs局部变量

pow*_*put 3 ocaml global-variables local-variables

我想创建一个名为result的全局变量,它使用5个字符串连接来创建一个包含字符串start的9倍的字符串,用逗号分隔.我有两段代码,只有第二段代码声明了一个全局变量.由于某种原因,它不能轻易地在我的大脑中注册......难道只是因为我使用了一个let in,所以第一段代码的结果是一个局部变量?有更详细的解释吗?

let start = "ab";;

let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result;;
- : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"

let result = 
  let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result;;
val result : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"
Run Code Online (Sandbox Code Playgroud)

ivg*_*ivg 5

让我成为一个有点无聊的人.OCaml中没有本地和全局变量.这个概念来自具有不同范围规则的语言.此外,应谨慎使用"变量"一词.其含义被类C语言所歪曲.这个词的原始数学意义对应于某个数学对象的名称,该名称在公式内使用,表示一系列此类值.在类C语言中,变量与内存单元混淆,后者可能会随时间变化.因此,为了避免混淆,让我们使用更准确的术语.让我们使用单词名称而不是变量.因为,变量......抱歉名称不是内存单元格,所以没有什么可以创建的.当您使用其中一种let语法时,实际上是在创建绑定,即名称和值之间的关联.所述let <name> = <expr-1> in <expr-2>结合在的范围的值<expr-2>表达.在let <name> = <expr-1> in <expr-2>由其自身也是一个表达式,因此,例如<expr-2>还可以含有let ... in ...构建体的内部,例如,

 let a = 1 in
   let b = a + 1 in
     let c = b + 1 in 
       a + b + c
Run Code Online (Sandbox Code Playgroud)

我特别是,以非惯用的方式缩进代码以突出表达式的句法结构.OCaml还允许使用已在范围内绑定的名称.新绑定将隐藏现有绑定(例如,在C中不允许),例如,

  let a = a + 1 in
    let a = a + 1 in
      let a = a + 1 in
          a + a + a
Run Code Online (Sandbox Code Playgroud)

最后,顶级(又称模块级别)let-binding(在OCaml用语中称为定义)具有语法:let <name> = <expr>,注意这里没有in.该定义将词汇范围<name>中的评估结果与从<expr>定义点延伸到封闭模块末尾的结果绑定在一起.在实现模块时,必须使用let <name> = <expr>将代码绑定到名称(可以使用省略名称_).它与交互式顶层(交互式ocaml程序)略有不同,它实际上接受一个表达式并对其进行求值.例如,

let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result
Run Code Online (Sandbox Code Playgroud)

不是有效的OCaml程序(可以放入ml文件并编译的东西).因为它是表达式,而不是模块定义.