在OCaml中打印嵌套列表

伊斯特万

我正在将一些Clojure代码移植到OCaml,但遇到了以下问题:

let rotate ll =
    let cons x y = x :: y in
    let init = List.map (fun _ -> []) (List.hd ll) in
    let rres = List.fold_right (List.map2 cons) ll init in
    List.rev rres;;

let rec spiral_print matrix acc =
    match matrix with
    | [] -> acc
    | head :: tail -> spiral_print (rotate tail)  (acc @ head);;

不幸的是,这导致以下结果:

utop # spiral_print [[1; 2; 3]; [8; 9; 4]; [7; 6; 5]] [];;
Exception: (Failure hd).

我想调试为什么会这样,但是当我打开trace时,这就是我得到的:

#trace spiral_print;;
spiral_print [[1; 2; 3]; [8; 9; 4]; [7; 6; 5]] [];;
spiral_print <-- [[<poly>; <poly>; <poly>]; [<poly>; <poly>; <poly>]; [<poly>; <poly>; <poly>]]
spiral_print --> <fun>
spiral_print* <-- []
spiral_print <-- [[<poly>; <poly>]; [<poly>; <poly>]; [<poly>; <poly>]]
spiral_print --> <fun>
spiral_print* <-- [<poly>; <poly>; <poly>]
spiral_print <-- [[<poly>; <poly>]; [<poly>; <poly>]]
spiral_print --> <fun>
spiral_print* <-- [<poly>; <poly>; <poly>; <poly>; <poly>]
spiral_print <-- [[<poly>]; [<poly>]]
spiral_print --> <fun>
spiral_print* <-- [<poly>; <poly>; <poly>; <poly>; <poly>; <poly>; <poly>]
spiral_print <-- [[<poly>]]
spiral_print --> <fun>
spiral_print* <-- [<poly>; <poly>; <poly>; <poly>; <poly>; <poly>; <poly>; <poly>]
spiral_print* raises (Failure hd)
spiral_print* raises (Failure hd)
spiral_print* raises (Failure hd)
spiral_print* raises (Failure hd)
spiral_print* raises (Failure hd)
Exception: (Failure hd).

有没有办法以某种方式检查单个函数执行的内部状态以捕获错误?

我会使用其他语言的印刷品或精美印刷品。

静脉血

ocamldebug 除非您限制类型,否则顶层将拒绝打印多态容器的元素:

let int_spiral_print : int list list -> int list -> int list = spiral_print;;
val int_spiral_print : int list list -> int list -> int list = <fun>
# #trace int_spiral_print;;
int_spiral_print is now traced.
# int_spiral_print [[1; 2; 3]; [8; 9; 4]; [7; 6; 5]] [];;
int_spiral_print <-- [[1; 2; 3]; [8; 9; 4]; [7; 6; 5]]
int_spiral_print --> <fun>
...

但是在这里具有正常的回溯将更有生产力。要获取它,请将您的代码放入文件中,例如,

$ cat spiral_print.ml

let rotate ll =
  let cons x y = x :: y in
  let init = List.map (fun _ -> []) (List.hd ll) in
  let rres = List.fold_right (List.map2 cons) ll init in
  List.rev rres

let rec spiral_print matrix acc =
  match matrix with
  | [] -> acc
  | head :: tail -> spiral_print (rotate tail)  (acc @ head)

let _ =
  Printexc.record_backtrace true;
  spiral_print [[1; 2; 3]; [8; 9; 4]; [7; 6; 5]] []

请注意,我添加Printexc.record_backtrace true了启用通常被禁用的回溯记录的功能。您也可以使用环境变量启用它OCAMLRUNPARAM=b然后,您可以编译并运行程序,以获得良好的回溯信息:

ocamlbuild spiral_print.d.byte --
Fatal error: exception Failure("hd")
Raised at file "pervasives.ml", line 30, characters 22-33
Called from file "spiral_print.ml", line 3, characters 36-48
Called from file "spiral_print.ml", line 10, characters 33-46
Called from file "spiral_print.ml", line 14, characters 2-51

适当的文本编辑器(aka emacs)甚至会为您突出显示异常源是(List.hd ll)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章