OCaml或Core中是否有通用调试打印?

时间:2016-01-21 23:49:07

标签: ocaml

假设我有一个类似type foo = string * string list的用户定义类型,如果我想在我的代码中插入打印调试语句以查看它包含哪些值,那么最快的方法是什么?

好像写作 let (first, second) = foo in printf "%s, %s" first (String.concat second) 对于快速而脏的调试语句来说,这是一种太多的工作方式!

3 个答案:

答案 0 :(得分:4)

一种选择是使用ppx_sexp_conv。如果您正在使用Core,则无需执行任何特殊操作。加载core可为您提供所需的一切。只需将[@@deriving sexp]添加到所有类型定义中即可。例如:

# type foo = string * string list [@@deriving sexp];;
type foo = string * string list
val foo_of_sexp : Sexp.t -> foo = <fun>
val sexp_of_foo : foo -> Sexp.t = <fun>

# let foo = "hello", ["how"; "are"; "you"];;
val foo : string * string list = ("hello", ["how"; "are"; "you"])

# sexp_of_foo foo |> Sexp.to_string_hum;;
- : string = "(hello (how are you))"

对于没有预先定义的类型,也可以动态生成sexp函数。例如:

# [%sexp_of: string * int];;
- : string * int -> Sexp.t = <fun>

# [%sexp_of: string * int] ("foo", 42);;
- : Sexp.t = (foo 42)

答案 1 :(得分:3)

您可以尝试使用&#34; OCaml电池中的BatPervasives.dump功能&#34;图书馆。使用opam install batteries安装,然后:

open Batteries

type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree

let t1 = Node(1, Leaf, Leaf)
let t2 = Node(2, t1, Leaf)
let t3 = Node(3, Leaf, t2)

let () = print_endline (dump t3)

构建:

ocamlfind ocamlc -package batteries -linkpkg testdump.ml

或:

ocamlbuild -pkg batteries testdump.byte

运行它应该产生:

(3, 0, (2, (1, 0, 0), 0))

正如您所看到的,与REPL输出(它依赖于Obj模块)相比,它有点剥离表示,但如果您知道类型,则通常很容易理解超出价值。

答案 2 :(得分:0)

这不属于Core,但是deriving是一个简化类型驱动的代码生成的库,而功能show可以满足您的要求,同时以比JSON更接近SEXP的格式进行打印。

来自文档:

# type file = {
  name : string;
  perm : int     [@printer fun fmt -> fprintf fmt "0o%03o"];
} [@@deriving show];;
# show_file { name = "dir"; perm = 0o755 };;
- : string = "{ name = \"dir\"; perm = 0o755 }"