Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OCaml:如何安装漂亮的打印机并在代码中使用它?_Ocaml_Pretty Print - Fatal编程技术网

OCaml:如何安装漂亮的打印机并在代码中使用它?

OCaml:如何安装漂亮的打印机并在代码中使用它?,ocaml,pretty-print,Ocaml,Pretty Print,在OCaml的顶级和调试器中,可以注册一台漂亮的打印机 通过安装打印机名称。 除了OCaml代码之外,有没有其他方法可以实现同样的效果? 更具体地说,我需要一个不需要 为每次调用log显式指定漂亮的打印机。 也就是说,类似于: (* First, user sets a global pretty-printer for a type *) let pp_foo : Foo -> string = ... let () = Logging.register pp_foo ... (* T

在OCaml的顶级和调试器中,可以注册一台漂亮的打印机 通过
安装打印机名称
。 除了OCaml代码之外,有没有其他方法可以实现同样的效果? 更具体地说,我需要一个不需要 为每次调用
log
显式指定漂亮的打印机。 也就是说,类似于:

(* First, user sets a global pretty-printer for a type *) 
let pp_foo : Foo -> string = ...
let () = Logging.register pp_foo
...
(* Then it can be used like that *)
let foo : Foo = ...
let () = Logging.log foo

这是不可能的,原因有二:

首先,OCaml在运行时擦除类型。因此,无法区分具有相同内存表示的值。例如,
[]
0
None
在编译后具有相同的表示

其次,
log
函数的类型是
'a'a->unit
。换句话说,该规范规定,您的函数日志应该适用于过去、现在和将来的任何类型。仅当函数忽略其参数时,才可能出现这种情况,例如:

let f _x = g ()
换句话说,真正的问题可能是你的问题是什么

let () = Logging.log pp_foo foo

由于两个原因,这是不可能的:

首先,OCaml在运行时擦除类型。因此,无法区分具有相同内存表示的值。例如,
[]
0
None
在编译后具有相同的表示

其次,
log
函数的类型是
'a'a->unit
。换句话说,该规范规定,您的函数日志应该适用于过去、现在和将来的任何类型。仅当函数忽略其参数时,才可能出现这种情况,例如:

let f _x = g ()
换句话说,真正的问题可能是你的问题是什么

let () = Logging.log pp_foo foo

与Octachron所说的不矛盾,但实际上有可能获得一些倾倒设施,这将是多态的。它将是脆弱的,实际上不会区分
[]
0
None
,但在OCaml内置类型中工作得很好。例如,可以在不同修改的库中找到此函数,并且库在
dump
名称下提供了一个函数,下面是与它进行顶级交互的示例:

# #use "topfind";;
# #require "extlib";;
# Std.dump;;
- : 'a -> string = <fun>
# Std.dump ["hello"; "world"];;
- : string = "[\"hello\"; \"world\"]"
# Std.dump [];;
- : string = "0"
# Std.dump None;;
- : string = "0"
# Std.dump [|"hello"|];;
- : string = "(\"hello\")"
# module Abstract : sig type t val x : t end = 
   struct type t = string list let x = ["hello, world"] end;;
module Abstract : sig type t val x : t end
# Std.dump Abstract.x;;
- : string = "[\"hello, world\"]"
# 
##使用“topfind”;;
##需要“extlib”;;
#标准垃圾场;;
-:'a->string=
#Std.dump[“你好”;“世界”];;
-:string=“[\“你好”;\“世界\]”
#标准转储[];;
-:string=“0”
#标准无;;
-:string=“0”
#Std.dump[|“你好”|];;
-:string=“(\“hello\”)”
#模块摘要:sig类型t val x:t end=
struct type t=string list让x=[“hello,world”]end;;
模块摘要:sig类型t val x:t end
#标准dump Abstract.x;;
-:string=“[\”你好,世界\]”
# 
有了这些能力,我仍然建议您仅将其用于调试目的


最后,如果你想知道顶级漂亮的打印是如何工作的,下面是答案。事实上,它依赖于类型化环境,该环境可用于顶级,部分是解释器,部分是编译器。这个漂亮的印刷设备仍然相当脆弱

这与Octachron的说法并不矛盾,但实际上有可能获得一些倾倒设施,这将是多态的。它将是脆弱的,实际上不会区分
[]
0
None
,但在OCaml内置类型中工作得很好。例如,可以在不同修改的库中找到此函数,并且库在
dump
名称下提供了一个函数,下面是与它进行顶级交互的示例:

# #use "topfind";;
# #require "extlib";;
# Std.dump;;
- : 'a -> string = <fun>
# Std.dump ["hello"; "world"];;
- : string = "[\"hello\"; \"world\"]"
# Std.dump [];;
- : string = "0"
# Std.dump None;;
- : string = "0"
# Std.dump [|"hello"|];;
- : string = "(\"hello\")"
# module Abstract : sig type t val x : t end = 
   struct type t = string list let x = ["hello, world"] end;;
module Abstract : sig type t val x : t end
# Std.dump Abstract.x;;
- : string = "[\"hello, world\"]"
# 
##使用“topfind”;;
##需要“extlib”;;
#标准垃圾场;;
-:'a->string=
#Std.dump[“你好”;“世界”];;
-:string=“[\“你好”;\“世界\]”
#标准转储[];;
-:string=“0”
#标准无;;
-:string=“0”
#Std.dump[|“你好”|];;
-:string=“(\“hello\”)”
#模块摘要:sig类型t val x:t end=
struct type t=string list让x=[“hello,world”]end;;
模块摘要:sig类型t val x:t end
#标准dump Abstract.x;;
-:string=“[\”你好,世界\]”
# 
有了这些能力,我仍然建议您仅将其用于调试目的

最后,如果你想知道顶级漂亮的打印是如何工作的,下面是答案。事实上,它依赖于类型化环境,该环境可用于顶级,部分是解释器,部分是编译器。这个漂亮的印刷设备仍然相当脆弱