不理解 Ocaml 类型签名

Not understanding Ocaml type signatures

我一直在努力理解这一点,在这方面再努力会伤害我与 OCaml 的关系,所以我想我会寻求帮助。

我有一个来自 this site

的简单函数
let line_stream_of_channel channel =
Stream.from
  (fun _ ->
     try Some (input_line channel) with End_of_file -> None);;

好酷,从下面的签名看就清楚了:

val line_stream_of_channel : in_channel -> string Stream.t = <fun>

in_channel 是参数,Stream.t 是 return 值。

为什么在 OCaml 中我做不到:

Stream string

而我必须做

string Stream.t

查看 the type signature of Stream 也没有真正让我有任何收获。我注意到同样的语法怪异,比如列表之类的东西,你必须在其中做不自然的事情

string list

而非自然

list string

但特别奇怪的是上面 Stream 类型的“.t”部分。

谁能解释一下这是怎么回事,为什么要这样做?我在 google 上搜索了关于 OCaml 中显式类型签名、类型等的教程,一般来说,它们会回到这里来解决对我没有真正帮助的非常具体的问题。

谢谢!

在 OCaml 的参数化类型中,类型构造函数名称位于参数名称之后。这就是它的工作方式。有些语言(例如 Haskell)使用其他顺序。

我喜欢 OCaml 命令,我没有问题。其他订单我也没有问题。

名称t 被定义为Stream 模块中的参数化类型。没有比这更棘手的了。

但是请注意,line_stream_of_channel 的 return 类型是 string Stream.t,而不仅仅是 Stream.tStream.t 本身不是一种类型。 (它是类型级别的函数,或类型构造函数。)

$ ocaml
        OCaml version 4.01.0

# Some 3;;
- : int option = Some 3
# ^D

$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Prelude> :t Just (3 :: Integer)
Just (3 :: Integer) :: Maybe Integer

OCaml 中的类型可以是参数化的。例如int list是一个参数化为int类型的列表,在其他一些语言中基本对应list<int>。很奇怪吗?这取决于你的背景。我个人觉得 string list 更自然,然后 list string

参数化类型的语法是<parameter-type> <parametrized-type>。所以这两个组件都应该是类型。 Stream 不是类型,是模块名。符号 <module-name> . <name> 允许您寻址模块中定义的定义。例如,您可以定义一个类型别名:

 type 'a stream = 'a Stream.t

然后使用它

 type string_stream = string stream

请注意,stream_string 听起来很奇怪,不是吗?