Opa / Opalang:设置或访问带有绑定的记录字段标签

时间:2014-01-30 12:09:41

标签: opa

在javascript中,可以使用点或方括号表示法在对象中获取或设置值,例如:

var a = {b: "c"};
alert(a.b);
alert(a["b"]);

两个警报都会产生相同的结果。

在Opa中是否有任何等效的方括号表示法,以便您可以设置标签以及带有绑定的记录字段的值?

我问这个,因为我在Opa中有以下代码:

(User.current_server_user, User.flower_hierarchy -> void) set_flower_hierarchy =

  function(current_user, flower_hierarchy) {

    match(current_user.user_data.cell) {

      case {none}: void

      case {some: cell}: {

        server_user_cell_data_opt = Cell.call(cell, {get})

        new_cell_data = match(server_user_cell_data_opt) {

          case {none}: {base_server_user_cell_data with ~flower_hierarchy}
          case {some: cell_data}: {cell_data with ~flower_hierarchy}

        }

        _ = Cell.call(cell, {set: some(new_cell_data)})
        void

      }

    }

  }

目前,我看不到使用flower_hierarchy以外的值设置new_cell_data的方法,而没有完全复制该函数来设置其他字段。

2 个答案:

答案 0 :(得分:0)

Opa和Javascript在哲学上有很大的不同。 Javascript是一种动态语言,不提供类型安全性。当您执行a[b]之类的操作时,您需要确保对象b中存在引用变量a的字段,否则您将获得undefined

另一方面,Opa是类型安全的,并确保所有表达“有意义”;你不必担心未定义的值。

如此简短的回答是:Opa中没有a[b]。但是,我非常有信心,你正在尝试做的事情可以在语言中得到优雅的表达。你能用语言解释你希望set_flower_hierarchy函数做什么吗? (我不清楚只看一下片段。)

答案 1 :(得分:0)

感谢您的回答。我暂时不能透露我的工作,但不想把它描述为“优雅”(虽然语言当然是这样),这是一种表达我想要做的更令人满意的方式。

首先,我需要定义一个变量类型,其中包含我想要在单元格中设置的不同值,以便它可以进行模式匹配,而不会让编译器抱怨未满足的情况。在这种情况下,附加值称为“dbid”:

type User.set_server_user_cell_data =
  {User.flower_hierarchy flower_hierarchy} or
  {User.dbid dbid}

然后我需要一个函数来设置单元格包含的新记录:

private (User.server_user_cell_data, User.set_server_user_cell_data
  -> User.server_user_cell_data) get_server_user_cell_data_record =

  function(cell_data, set_cell_data) {

    match(set_cell_data) {

      case {~flower_hierarchy}: {cell_data with ~flower_hierarchy}
      case {~dbid}: {cell_data with ~dbid}

    }

  }

我原来的“set_flower_hierarchy”函数中的代码可以这样抽象出来:

private (User.current_server_user, User.set_server_user_cell_data
  -> void) set_server_user_cell_field =

  function(current_user, field) {

    match(current_user.user_data.cell) {

      case {none}: void

      case {some: cell}: {

        server_user_cell_data_opt = Cell.call(cell, {get})

        new_cell_data = match(server_user_cell_data_opt) {

          case {none}:
            get_server_user_cell_data_record(base_server_user_cell_data, field)

          case {some: cell_data}: 
            get_server_user_cell_data_record(cell_data, field)

        }

        _ = Cell.call(cell, {set: some(new_cell_data)})
        void

      }

    }

  }