Search code examples
functionsml

How to 'RUN' Zero-Argument Function in SML


If there were a function foo like this:

fun foo() = 10

When I want to run the foo, I wrote like this:

val bar = foo

But bar becomes a function (unit->int) not 10

So I tried like this:

val int bar = foo

But it makes error. So I tried like this:

fun foo x = 10

val bar = foo 0

Finally I get bar = 10, but it looks horrible.

So, what should I do for run the zero-argument function without change anything?


Solution

  • You might be thinking of some other languages, where () would mean an empty parameter list.
    In SML, it doesn't.

    foo doesn't take zero arguments; it takes exactly one argument: ().

    - fun foo () = 10;
    val foo = fn : unit -> int
    

    As you can see, foo is a function from unit to int.

    - ();
    val it = () : unit
    

    () (usually pronounced "unit") is the only value of the unit type.
    (The word "unit" can mean "a single thing", which is exactly what the type is.)

    To call the function, pass it an argument of type unit:

    - foo ();
    val it = 10 : int
    

    You can of course also bind a name to ():

    - val kittens = ();
    val kittens = () : unit
    - foo kittens;
    val it = 10 : int
    

    Side note: you may think this is odd if you compare to, say,

    - fun bar (x,y) = x + y;
    val bar = fn : int * int -> int
    

    but bar also takes just one argument, of type int * int.
    We usually say that it takes two, but from the type system's point of view there is only one argument (which is a pair).