我一直在努力去理解这一点,并且更加努力地工作会伤害我与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是返回值。
为什么在OCaml中我无法做到:
Stream string
而我必须做
string Stream.t
看着the type signature of Stream并没有让我到任何地方。我已经注意到同样的语法怪异与列表之类的东西,你必须做不自然的
string list
而不是自然
list string
但是特别奇怪的是&#34; .t&#34;上面Stream类型的一部分。
任何人都可以解释这里发生了什么以及为什么这样做了?我已经在OCaml中搜索了关于显式类型签名,类型等的教程,一般来说,他们会回到非常具体的问题,这些问题并不能帮助我。
谢谢!
答案 0 :(得分:1)
在OCaml的参数化类型中,类型构造函数名称位于参数名称之后。这就是它的工作方式。有些语言(例如Haskell)使用其他顺序。
我喜欢OCaml订单,我没有问题。我对其他订单也没有问题。
名称t
在Stream
模块中定义为参数化类型。没有比这更棘手的了。
但请注意,line_stream_of_channel
的返回类型为string Stream.t
,而不仅仅是Stream.t
。 Stream.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
答案 1 :(得分:0)
类型可以在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
听起来很奇怪,不是吗?