Reputation: 729
I have been working on trying to understand this, and working any harder on it is going to hurt my relationship with OCaml, so I figured I would ask for help.
I have a simple function from this site
let line_stream_of_channel channel =
Stream.from
(fun _ ->
try Some (input_line channel) with End_of_file -> None);;
Okay cool, clearly from the signature below it:
val line_stream_of_channel : in_channel -> string Stream.t = <fun>
in_channel is the argument and Stream.t is the return value.
Now why is it in OCaml that I can't do:
Stream string
and instead I have to do
string Stream.t
Looking at the type signature of Stream didn't really get me anywhere either. I've noticed this same syntax weirdness with stuff like lists where you have to do the unnatural
string list
rather than the natural
list string
But what is especially weird is the ".t" portion of the Stream type above.
Can anyone kinda explain what is going on here and why things are done this way? I've googled tutorials on explicit type signatures, types, etc in OCaml and in general they lead back here to very specific questions that don't really help me.
Thank you!
Upvotes: 1
Views: 564
Reputation: 35280
Types can be parametric in OCaml. For example, int list
is a list parametrized with type int
, and basically corresponds to list<int>
in some other languages. Is it weird? It depends on your background. I personally, find string list
more natural, then list string
The syntax for parametrized type is <parameter-type> <parametrized-type>
. So both components should be types. Stream
is not a type, it is a module name. The notation <module-name> . <name>
allows you to address definitions defined in module. For example, you may define a type alias:
type 'a stream = 'a Stream.t
and then use it
type string_stream = string stream
Note, stream_string
sounds weird, isn't it?
Upvotes: 0
Reputation: 66823
In OCaml's parameterized types, the type constructor name comes after the parameter name(s). That's just the way it works. There are languages (such as Haskell) that use the other order.
I like the OCaml order, I have no problem with it. I also have no problem with the other order.
The name t
is defined as a parameterized type in the Stream
module. There's nothing trickier than this going on.
However, note that the return type of line_stream_of_channel
is string Stream.t
, not just Stream.t
. Stream.t
by itself isn't a type. (It's a function at the type level, or a type constructor.)
$ 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
Upvotes: 1