在OCaml中打印变体类型 [英] Printing variant types in OCaml

查看:113
本文介绍了在OCaml中打印变体类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的OCaml程序中,我花了很多时间反复为变体类型拧"to_string".我可能出于调试目的需要它们,或者因为我需要特定的格式化输出.

In my OCaml program, I spend considerable time wring "to_string" for variant types over and over again. Either I need them for debugging purpose, or because I need a specific formatted output.

到目前为止,他们遵循的模板如下:

So far, they follow a template such as follows:

let rec to_string = function                                                                                                               
    | Var x -> x                                                                 
    | Implies (f1, f2) -> Printf.sprintf "(=> %s %s)" (to_string f) (to_string f2)
    | And (f1, f2) -> Printf.sprintf "(& %s %s)" (to_string f1) (to_string f2)   
    | Or (f1, f2) -> Printf.sprintf "(| %s %s)" (to_string f1) (to_string f2)    
    | Not (f) -> Printf.sprintf "(~ %s)" (to_string f)                           
    | True -> "#t"                                                               
    | False ->"#f"        

我想知道是否还有比这更方便/常规的方式,可能与语言的最新发展有关.例如,根据类型自动生成模板?可以用于调试的通用打印功能?

I'm wondering if there are more convenient/conventional ways of than this, possibly with the latest development of the language. For instance, automatic generation of templates based on the type? generic printing functions that could be used for debugging?

"Real World OCaml"中提倡的一种方法是使用Core库的Sexp模块,该模块为此目的提供了便利.如果您不需要关于如何打印值的大量自定义操作,则此方法似乎很好用.我想知道是否还有其他/更好的选择.

One way advocated in "Real World OCaml" is to use the Sexp module of the Core library that provides facilities for this very purpose. It seems to work well if you don't need much customization about how you print the values. I'd like to know if there are other/better options.

推荐答案

基于类型的生成器很少,您可能会发现它们很有趣,例如derivingtyperepsexplib等.但是我确实没想到,有一种神奇的东西会在编译时读懂您的思想,并根据您的喜好和感觉编写漂亮的打印函数.关于模板,所有模板引擎都是某种模式匹配(通常是字符串类型),而OCaml已经为您提供了现成的模式匹配.同样不要忘记,您的类型定义是递归的,这使得基于模板的方法更难使用.您可以使用一些基于jsonxml的自动转储器,例如ocaml-cow并实现某种xslt转换,但是最终会得到很多代码,这些代码实际上是在重新发明OCaml的本机模式匹配.

There're few type-based generators, that you may found interesting, like deriving, typerep, sexplib, etc. But I do not expect, that there is something magical, that will read your mind on compile time and write a pretty-printing functions according to your taste and feelings. What concerning templating, then all of the templating engines are some kind of pattern-matching, (usually stringly typed), and OCaml already provides you pattern-matching out of box. And also do not forget, that your type definition is recursive and this makes template based approaches much harder to use. You can use some automatic json or xml based dumper, like ocaml-cow and implement some kind of xslt transformation, but you will end up with lots of code, that are actually reinventing OCaml's native pattern matching.

因此,对于像您这样的小语言,编写此to_string函数是最佳解决方案.我认为这是将您的想法表达给计算机的最自然的方法.我也建议使用Format模块,并使用%a说明符递归.此外,Format模块具有tags的概念.标签允许按字面意义标记格式字符串中的文本, 标记的格式可以通过以下示例进行说明:

So, for small languages, like yours, writing this to_string functions is the best solution. I think that this is the most natural way to express your idea to computer. I would also suggest to use Format module, and recurse using %a specifiers. Also, Format module, has concepts of tags. Tags allows to literally tag pieces of text in format strings, the format of tagging can be explained with the following example:

@{<html>@{<head>@{<title>Tags!@}@}@{<body>Hello!@}@}

这可以自动传输到HTML:

This can be automatically transferred to HTML:

  <html>
   <head>
    <title>
    Tags!
    </title>
   </head>
   <body>
   Hello!
   </body>
  </html>

也可以将其传输到LaTeXjson或其他任何内容,包括什么都不要(即完全忽略标签).但是,标记更多是关于处理格式和元信息,例如语法高亮显示和引用.它们实际上不会影响具体语法.

One can also, transfer it to LaTeX, json, or anything else, including to nothing (i.e., ignoring tags at all). But Tags are more about handling formatting and meta information, like syntax higlighting and referencing. They can't actually influence on concrete syntax.

对于丰富的语法树,编写漂亮打印功能的递归集的方法不能很好地扩展.这就是为什么OCaml中有O的原因.您可以使用开放式递归来实现带有很多钩子(即方法)的AST-visitor分类.这是OCaml本身和camlp4中使用的方法.

For rich syntax trees the approach of writing recursive set of pretty-printing function doesn't scale well. And that's why there is O in the OCaml. You can use open recursion to implement AST-visitor clasess with lots of hooks (i.e., methods). This is the approach that is used in OCaml itself and camlp4.

这篇关于在OCaml中打印变体类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆