1

In the book Real World OCaml, I find this code:

let command = 
  Command.basic
    ~summary:"Generate an MD5 hash of the input data" 
    Command.Spec.(
      empty
      ...
      +> anon (maybe_with_default "-" ("filename" %: file))
    )
    (fun use_string trial filename () ->

I see () in the last line (fun use_string trial filename ()).

Also from Print a List in OCaml, I also see () in the first match.

let rec print_list = function 
[] -> ()
| e::l -> print_int e ; print_string " " ; print_list l

Then, what's the meaning of () in both cases? How does the lambda expression (fun) have () in its parameter list?

Community
  • 1
  • 1
prosseek
  • 182,215
  • 215
  • 566
  • 871

1 Answers1

7

It's a nullary constructor, the sole constructor of type unit. The convention is to use this constructor to indicate "no particular value", which is common when working with effectful code.

Returning () is the ML way to return nothing.

When appearing in an argument list it is matched, just like any other constructor. This is a way to indicate there is no value for an argument. It's necessary to do this in ML because all functions are unary. You can't have a function with zero arguments, so instead you pass an argument containing no information, which is ().

didierc
  • 14,572
  • 3
  • 32
  • 52
gsg
  • 9,167
  • 1
  • 21
  • 23
  • 1
    Not only all ML functions take exactly one argument, but they also return exactly one result. So `()` is also what a function returns when it doesn't have any value it wants to return. Both are typical of effectful code: if `f` is pure and takes no arguments, there is no reason not to make it a constant instead, and if it has no result to return, that means that it is interesting for its effects. – Pascal Cuoq Feb 27 '15 at 10:11
  • 1
    The unit type is also useful in polymorphic data structures, such as a hash table used as just a set of keys (`(string, unit) Hashtbl.t`). – Martin Jambon Feb 27 '15 at 19:42