在 OCaml 中打印嵌套列表
Printing nested lists in 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 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).
有没有办法以某种方式检查各个函数执行的内部状态以捕获错误?
我会在其他语言中使用 print 或 pretty print。
我写了旋转代码:-)
如果传递一个空列表,该函数将失败。那是你的问题,我想。赠品是错误来自 List.hd
。如果列表是空的,你只需要决定你想要什么答案。可能答案是一个空列表。
let rotate ll =
if ll = [] then
[]
else
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 rotate = function
| [] -> []
| hd :: _ as ll ->
let cons x y = x :: y in
let init = List.map (fun _ -> []) hd in
let rres = List.fold_right (List.map2 cons) ll init in
List.rev rres
但要回答您的实际问题,您可以使用 ocamldebug 在执行期间检查值。
ocamldebug
以及 toplevel 将拒绝打印多态容器的元素,除非您限制类型:
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
适当的文本编辑器(又名 emacs)甚至会为您突出显示异常源是 (List.hd ll)
。
我正在努力将我的一些 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 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).
有没有办法以某种方式检查各个函数执行的内部状态以捕获错误?
我会在其他语言中使用 print 或 pretty print。
我写了旋转代码:-)
如果传递一个空列表,该函数将失败。那是你的问题,我想。赠品是错误来自 List.hd
。如果列表是空的,你只需要决定你想要什么答案。可能答案是一个空列表。
let rotate ll =
if ll = [] then
[]
else
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 rotate = function
| [] -> []
| hd :: _ as ll ->
let cons x y = x :: y in
let init = List.map (fun _ -> []) hd in
let rres = List.fold_right (List.map2 cons) ll init in
List.rev rres
但要回答您的实际问题,您可以使用 ocamldebug 在执行期间检查值。
ocamldebug
以及 toplevel 将拒绝打印多态容器的元素,除非您限制类型:
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
适当的文本编辑器(又名 emacs)甚至会为您突出显示异常源是 (List.hd ll)
。