ocamldebug 中多态类型的打印表达式
printing expressions of polymorphic type in ocamldebug
假设我们有一个要调试的多态函数,例如:
let rec rev lst = match lst with
| [] -> []
| x::xs -> List.append (rev xs) [x]
为了制作一个程序,我们添加一个主要功能:
let () = ignore (rev [1;2;3;4])
结果无关紧要,但请注意 rev 是使用 int 列表调用的,即非多态类型。
仍然当我在 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
.
您可以像在顶层中那样安装用户打印机。该命令在 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]
安装打印机的技巧将使您免于抽象类型,而不是多态。
假设我们有一个要调试的多态函数,例如:
let rec rev lst = match lst with
| [] -> []
| x::xs -> List.append (rev xs) [x]
为了制作一个程序,我们添加一个主要功能:
let () = ignore (rev [1;2;3;4])
结果无关紧要,但请注意 rev 是使用 int 列表调用的,即非多态类型。
仍然当我在 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
.
您可以像在顶层中那样安装用户打印机。该命令在 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]
安装打印机的技巧将使您免于抽象类型,而不是多态。