在ocamldebug中打印多态型的表达

时间:2015-03-23 18:17:34

标签: ocaml

我们说我们有一个我们想要调试的多态函数,例如:

let rec rev lst = match lst with
  | [] -> []
  | x::xs -> List.append (rev xs) [x]

要制作一个程序,我们添加一个主函数:

let () = ignore (rev [1;2;3;4])

结果是无关紧要的,但是注意rev用int列表调用,即非多态类型。

当我在ocamldebug中调试执行时,我只在打印list参数时得到一个通用列表:

(ocd) break @ Rev 1
(ocd) run
Breakpoint: 1
1 let rec rev lst = <|b|>match lst with
(ocd) print lst
lst: 'a list = [<poly>; <poly>; <poly>; <poly>]

我知道没有纯粹的(即非camlp4)方式来获得通用打印功能,但这种限制是否适用于ocamldebug?换句话说:是否可以在调试器中获取列表[1;2;3;4]而不是<poly>

修改 用户ivg建议通过#install_printer安装相应类型的打印功能。我创建了一个具有以下功能的新模块pp:

let rec pplist ch fmt = function
| [] -> ()
| x::xs -> 
   Format.fprintf ch "%s; " (fmt x); 
   pplist ch fmt xs

let int_list ch = pplist ch string_of_int

toplevel将类型正确报告为Format.formatter -> int list -> unit。 ocamldebug会话现在看起来如下:

(ocd) load_printer pp.cmo
File ./pp.cmo loaded
(ocd)  install_printer Pp.int_list
(ocd)  break @ Rev 1
Loading program... done.
Breakpoint 1 at 14768 : file rev.ml, line 1, characters 19-84
(ocd) 
(ocd) run
Time : 12 - pc : 14768 - module Rev
Breakpoint : 1
1 let rec rev lst = <|b|>match lst with
(ocd) print lst
lst : 'a list = [<poly>; <poly>; <poly>; <poly>]

但似乎ocamldebug不使用int_list并且需要多态'a list

1 个答案:

答案 0 :(得分:5)

您可以使用相同的方式安装用户打印机,就像在顶层中执行此操作一样。名为install_printer的命令在Manual中描述。例如,如果您的元素类型是抽象的,但提供了to_string函数,则可以为其编写打印机:

let pp ch x = Format.fprintf ch "%s" (to_string x)

然后使用上述指令安装打印机。

更新

以上只会打印具体类型。抽象值无法打印。唯一的方法是将它们(临时)限制为具体类型:

给定约束程序:

let rec rev lst : int list = match lst with
  | [] -> []
  | x::xs -> List.append (rev xs) [x]

ocd将打印列表:

Loading program... done.
Breakpoint 1 at 21448: file test.ml, line 1, characters 30-95
(ocd) run
Time: 12 - pc: 21448 - module Test
Breakpoint: 1
1 let rec rev lst : int list = <|b|>match lst with
(ocd) p lst 
lst: int list = [1; 2; 3]

安装打印机的技巧将使您免于抽象类型,而不是多态。