在OCaml中,如何在函数内重新分配全局变量

时间:2014-08-08 15:31:25

标签: global-variables ocaml

我的程序有以下全局变量:

let a = (0.0,0.0);;

以下,eval e1返回string_of_float,somefunc e2返回元组。

let rec output_expr = function
    Binop(e1, op, e2) -> 
            let onDist = float_of_string(eval e1) and onDir = somefunc e2 in 
            let newA = onDir in (
                   fprintf oc "\n\t%s" ("blah");
                   fprintf oc "\n\t%s" ("blah");
                   fprintf oc "\n\t%s" ("blah");
                   let a = newA
            )

现在,上面的代码给出了以下错误:

Error: This expression has type bool
       but an expression was expected of type unit
Command exited with code 2.

我希望let a = newA更改全局变量a的值。我怎么能这样做?

3 个答案:

答案 0 :(得分:3)

要做到这一点,你需要将值作为参考,

let a = ref (0.0, 0.0)

然后该状态可以改变,

a := (1.0, 2.0);

在功能性世界中,你不希望拥有这种全球状态。有时它非常有用,但在这种特殊情况下是值得怀疑的。您应该将值a传递给函数并返回可以在以后使用的新值(a');请注意,该值永远不会更改,但新值将取代并用于进一步计算。

在您的特定情况下,我认为您需要问问自己为什么名为output_expr的函数会修改某个全局状态,或返回除unit之外的任何内容。但也许这是我们消费的一个玩具示例,所以我会留下它。

答案 1 :(得分:3)

您无法在OCaml中分配变量(本地或全局相同)。语言中根本就没有语法。换句话说,OCaml中的变量是其他语言所谓的“常量” - 它们在初始化时获得一次值,就是这样。

但是,您可以使用可变数据结构,该结构提供了修改其内容的方法。数据结构是引用类型,您可以在变量中保存对数据结构的引用,并修改内容,而无需分配给变量。

nlucaroni提到了这样一个数据结构ref,它是一个包含所需类型值的简单可变单元格。还有其他可变数据结构,如数组,字符串和任何带有mutable字段的记录。每种方法都有自己修改内容的方式。

但是,在函数式编程中大多可以避免使用可变状态,如果依赖于可变状态,则可能表明您没有以功能方式执行此操作。

答案 2 :(得分:2)

在OCaml中,值是不可变的。您无法更改值的内容,应重新组织代码,以便您不需要。 在这里,您的函数output_expr应该返回newA,之后应该使用此值而不是a

实际上你可以使用引用来获取可变变量,但是如果你知道你做了什么并且认为它们更适合某个特定用例,那么你应该只使用它们,绝不会因为你不理解不变性。