Search code examples
typesocamlsignature

Not understanding Ocaml type signatures


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!


Solution

  • 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