【问题标题】:OCaml Binding a variable with nested typesOCaml 使用嵌套类型绑定变量
【发布时间】:2017-03-24 20:53:02
【问题描述】:

我是 OCaml 的新手,正在尝试加入一个大型 OCaml 项目。在跟踪构成其他类型的类型时,我试图思考如何使用它们,所以我将其分解为一个小例子,我认为它与大型项目中的情况非常接近。

如果我有由三个字段组成的记录类型expression

type expression = {e_id:int; e_node:exp_node; e_loc:location}
and exp_node =
  | Const of int
  | Lval of lval
  | SizeofStr of string
and lval =
  | Var of varinfo
  | Mem of expression
and location = {x:int; y:int}
and varinfo = {vname:string; vorigname:string}

如果e_node 字段是整数,我可以绑定这种类型的变量:

let exp_const = {e_id=10;
                 e_node= Const 10;
                 e_loc={x=10; y=10}}

现在,如果我希望 e_node 字段属于 Lval 类型,即记录类型 lval,我不知道该怎么做。我试过了:

let exp_lval_var =
  {e_id=11;
   e_node= {vname="int_val"; vorigname="int_val1"};
   e_loc={x=10; y=20}}

但它说This expression has type varinfo but an expression was expected of type exp_node。但如果你按照类型,它就是!?

我在这里没有正确定义类型吗?还是我没有正确使用类型?我真的找不到更多使用 OCaml 类型的复杂示例。如有任何建议,我们将不胜感激。

【问题讨论】:

    标签: types nested ocaml


    【解决方案1】:

    就像你写Const 10(而不是10)一样,你需要写Lval (Var { ... })来为你的e_node字段获得正确的值。

    let exp_lval_var =
      {e_id=11;
       e_node= Lval (Var {vname="int_val"; vorigname="int_val1"});
       e_loc={x=10; y=20}}
    

    按照第一个示例的类型:

    • 10int 类型
    • Const 10exp_node 类型

    第二个例子

    • {vname="int_val"; vorigname="int_val1"}varinfo 类型
    • Var {vname="int_val"; vorigname="int_val1"}lval 类型
    • Lval (Var {vname="int_val"; vorigname="int_val1"})exp_node 类型

    ConstVarLval 等值构造函数不仅仅是 OCaml 中文档的标签。它们必须作为表达式的一部分出现才能为其类型赋值。

    【讨论】:

    • 谢谢!这很有意义
    • 那么用我的exp_lval_var 如果我有这个并且想要访问与之关联的vname,我想要一个函数来获取它?在我遍历类型以获取 vname 记录元素的地方做一些事情并不是 Ocaml 惯用的,例如在 Printf.printf "%s" 的参数中? (我意识到副作用也不是真正地道的,因为它们是副作用)
    • 这样的函数是最好的选择吗:let get_vname {e_id=_; e_node=节点; e_loc=_} = 匹配节点 | const i -> Printf.sprintf "e_node is int: %i (no vname)" i | Lval lv -> (match lv with | Var {vname=vstring; vorigname=vostring} -> Printf.sprintf "%s to %s" vostring vstring | Mem _ -> "have expression") | SizeofStr sizestr -> Printf.sprintf "e_node is SizeofStr: %s (no vname)" sizestr 然后我可以像 Printf.printf "%s" (get_vname exp_lval_var);; 一样使用它
    • 实际上我看到我可以使该函数递归 Mem
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    相关资源
    最近更新 更多