在ocamldebug中打印多态类型的表达式

5

假设我们有一个多态函数需要调试,例如:

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

为了将其制作成一个程序,我们添加一个主函数:
let () = ignore (rev [1;2;3;4])

结果并不重要,但是请注意 rev 被调用时使用了一个整数列表,即非多态类型。
然而,当我在 ocamldebug 中调试执行时,当我打印列表参数时仍然只得到一个通用列表。
(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

顶层报告正确地显示类型为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个回答

5
您可以像在顶级中那样安装用户打印机。命令名为install_printer,并在手册中进行了描述。例如,如果您的元素类型是抽象的,但提供了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]

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


感谢指针 - 不知何故,ocamldebug 没有使用自定义的打印函数。我应该创建一个新问题还是你想回答这个问题?无论如何,我已更新了问题。 - lambda.xy.x
谢谢您提供的额外解释 - 这就是我最终所做的,但当通用代码与不同类型一起使用时,这有点令人烦恼。 - lambda.xy.x

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接