如何更改记录中的部分值?

时间:2011-07-01 20:23:45

标签: list ocaml record

我已经定义了类似的类型:

type s_program =
    { globals : s_var list;
      main: s_block; }
and s_var =
    { s_var_name: string;
      s_var_type: s_type;
      s_var_uniqueId: s_uniqueId }
and s_uniqueId = int

在我的计划中,我有一个变量p: s_program,但我需要更改s_var_uniqueId的每个元素的p.globals,例如,添加1s_var_uniqueIdp。我有一些问题:

1)我可以直接修改p':s_program中的相关值,还是必须为新let p' = { p with globals = List.map (fun var -> { var with s_var_uniqueId = var.s_var_uniqueId + 1 }) p.globals

分配新值?

2)我可以这样写:

with

非常感谢。

修改1:按建议更正{{1}}部分

2 个答案:

答案 0 :(得分:4)

首先,您可能需要阅读this section on record in OCamlthis chapter on modifiable data structures。如上所述,您将看到记录不可变。其次,你需要考虑你真正想要的东西:可变记录,带有可变字段的记录或带有可变字段的可变记录。例如,假设我们有复数的记录(这是ref 1中的相同示例)。

type complex = { re:float; im:float } ;;

如果您宣布类似

的内容
let c = {re=2.;im=3.} ;;

然后您既不能更改c也不能更改re(或im)。确实c := {re=4.;im=6.} ;;c.re := 4.;;都会因错误而失败。要获得可变记录,您只需使用c的引用。

let c = ref {re=2.;im=3.} ;;

然后,您可以使用c更改c := {re=4.;im=6.} ;;。但我认为你想拥有可变领域!然后你必须确定哪些字段是可变的。假设您希望所有字段都是可变的,您可以编写

type complex = { re:float ref; im:float ref }
let make_complex r i = { re = ref r ; im = ref i } 
let c = make_complex 3. 4.
;;

然后使用

更改字段
c.re := 6. ; c.im := 7. ;;

使用float -> float -> ()

类型的函数会更容易
let change_re c r = c.re := r ;;
let change_im c i = c.im := i ;;
let change_complex c r i = change_re c r ; change_im c i ;;

但是,我建议你真的考虑在你的代码中加入这样的命令功能。这可能是完全破坏其可读性的简单方法。

答案 1 :(得分:3)

1)这取决于您是否要将Ocaml用作命令式或函数式编程语言:)。如果是前者,则可以使记录的两个字段都可变(通过在字段名称之前添加可变关键字),然后在适当的位置更改它们。但是我强烈建议不要这样做并且:

2)使用你的第二种方法,看起来非常好(除了你似乎缺少{...}进行第二次修改。