Consider the following code:
let f a = if a > 5 then true
If you call f 10
, it returns true
.
Now, ask yourself this: what should f 2
return? I know you're going to say false
, but how does the compiler know that? I mean, it's just as likely that you meant it to return true
in both cases, isn't it? Or even, perhaps, crash in the a <= 5
case, who knows?
So in order for the program to be "complete" (i.e. contain instructions for what to do in every situation), you always have to specify an else
branch.
unit
, however, is special.
Returning unit
means that there is no meaningful return value. Essentially unit
stands for side-effect: it means that the thing that returned it was meant to produce some effect in the external world. Since F# is not a pure language, such unit
-returning things are quite ubiquitous. For example, debug logging:
let f x =
if x < 42 then printfn "Something fishy, x = %d" x
x + 5
With such statements, there is no ambiguity: it's always known that the else
branch is meant to return ()
as well. After all, there are no other values of unit
, are there? At the same time, always adding else ()
at the end would be very tiresome and obfuscating. So, in the interest of usability, the compiler doesn't require an else
branch in this specific case.