OCaml中类似于ghci的type指令是什么?

7
在ghci中,您可以使用类型指令type directive查找任何表达式的类型。
例如,如果我想找出\ f g h -> g (h f)的类型,我可以在ghci解释器中使用指令,像这样:
Prelude> :t \ f g h -> g (h f)
\ f g h -> g (h f) :: t2 -> (t1 -> t) -> (t2 -> t1) -> t

有没有OCaml的类似等效物?


2
这可能是一个重复的问题:如何在交互式Ocaml中获取类型信息? - cic
2个回答

14

您可能会发现utop toplevel对此非常有用。这是标准OCaml toplevel的增强版本,具有以下功能:

  • 更合理的交互式使用默认值(启用短路径)
  • 自动评估某些顶级单子,如Lwt或Async I/O(因此在顶级中键入int Deferred.t或int Lwt.t将返回int)
  • 交互式历史记录和模块完成以及所有编辑器的好处。

有两种方法可以查找某个东西的类型。对于一个值,只需将表达式输入到toplevel中:

$ utop
# let x = 1 ;;
val x : int = 1
# x ;;
- : int = 1

这适用于值,但不适用于类型定义。但是,utop(1.7+)还有一个#typeof指令,可以为您打印出来。

$ utop
# #typeof Unix.sockaddr
type Unix.sockaddr = ADDR_UNIX of string | ADDR_INET of Unix.inet_addr * int
# #typeof ref
type 'a Pervasives.ref = { mutable contents : 'a; }

(最后一个示例表明ref引用类型只是单个可变contents字段的语法糖。)

快速转储模块定义的另一种常见技巧是将其别名为新模块。

$ utop
# module L = List ;;
module L : sig
  val hd : 'a list -> 'a
  val tl : 'a list -> 'a list
  val nth : 'a list -> int -> 'a
  <etc>

您可以通过opam install utop快速安装utop。在《Real World OCaml》中,我们建议初学者使用这个作为首选的交互式编辑器,而不是原始的OCaml toplevel。


@JasonYeo 注意,上述用法1和3并不特定于utop - lukstafi
太棒了!#typeof正是我想要的!谢谢! - Jason Yeo
我觉得 #typeof 这个名称与其所表示的功能有些奇怪。你并不是获取一个类型的类型,而是打印出这个类型的定义。我更喜欢 #showdef - Ashish Agarwal
模块别名技巧对我不起作用。它只是打印“module L = Core.Std.List”,而不是模块签名。我正在使用Ocaml版本4.02的utop 1.15。 - hugomg

5

只需在OCaml解释器中输入函数,其类型会自动显示

# fun f g h -> g (h f);;
- : 'a -> ('b -> 'c) -> ('a -> 'b) -> 'c = <fun>

有没有一种方法可以在不对表达式进行任何评估的情况下获取表达式的类型? - Daniel Wagner
@DanielWagner 把它放在一个文件中,然后输入 ocamlc -i。还有另一种方法,涉及到 ocamlc -annot - Pascal Cuoq

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