【问题标题】:How can I define notation in OCaml?如何在 OCaml 中定义符号?
【发布时间】:2020-11-03 17:49:56
【问题描述】:

我正在尝试为我在 OCaml 项目中定义的类型定义符号。基本上,这种类型允许我表达一个类型的一个或两个值,我称之为maybe_pair。我希望能够编写一些符号来定义这种类型的值,例如:

  • 对于单个值,我们可以写成<5> : int maybe_pair
  • 对于两个值,我们可以写成<3;7> : int maybe_pair

我基本上是在尝试模仿列表符号的工作方式,但我相信这可能是不可能的。

【问题讨论】:

    标签: ocaml notation


    【解决方案1】:

    你不能仅仅通过定义 OCaml 函数来获得你想要的符号。您可以将 <> 定义为中缀运算符(具有固定的预定义优先级),但您不能将它们定义为像括号一样成对工作。

    您可以使用 OCaml 语法扩展机制 ppx 获得任何所需的语法。但这是一个很大的主题,对于 StackOverflow 上的答案来说太大了(在我看来)。

    您可以在此处阅读有关 PPX 的信息:https://ocamlverse.github.io/content/ppx.html

    在这里:https://github.com/ocaml-ppx/ppxlib

    【讨论】:

      【解决方案2】:

      下面的类型可以保存一个或两个'a类型的值:

      type 'a maybe_pair = Single of 'a | Double of 'a * 'a
      

      【讨论】:

      • 抱歉,我可能不够清楚。我已经定义了类型,它看起来和你的很相似,但我想要特定的符号,就像我在我的问题中输入的那样。
      • 您是在尝试使用这种表示法解析文件还是在 OCaml 代码中使用这种表示法?你能给我们更多的背景吗?
      【解决方案3】:

      您可以编写一个 ppx-rewriter 来部分实现您的目标,尽管不支持带尖括号的表示法。

      我假设这对定义如下:

      (* file: pair.ml *)
      
      type 'a maybe_pair = MkPair of 'a * 'a option [@@deriving show]
      

      ppx 扩展名应如下所示:

      (* file: ppx_pair.ml *)
      
      open Ppxlib
      
      let name = "mp"
      
      let expand ~loc ~path:_ expr =
        match expr with
        | {pexp_desc = Pexp_sequence (e1,e2); _} -> [%expr Pair.MkPair ([%e e1], Some [%e e2]) ]
        | e1 -> [%expr Pair.MkPair ([%e e1], None) ]
      
      
      
      let ext =
        Extension.declare name Extension.Context.expression
          Ast_pattern.(single_expr_payload __)
          expand
      
      
      let () = Driver.register_transformation name ~extensions:[ext]
      

      我们可以看到它的作用如下:

      let () =
        let x = [%mp 1] in
        Format.printf "x is %a\n" (Pair.pp_maybe_pair Format.pp_print_int) x;
        let x = [%mp 1; 2] in    
        Format.printf "x is %a\n" (Pair.pp_maybe_pair Format.pp_print_int) x
      

      输出:

      x is (Pair.MkPair (1, None))
      x is (Pair.MkPair (1, (Some 2)))
      

      我在这里做了一个最低限度的工作示例项目结构: https://gitlab.com/gopiandcode/example-ppxlib

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-12
        相关资源
        最近更新 更多