If I have the following function:
let myFunc x y =
if y = 0 then 1
x
I get the error:
Program.fs(58,17): error FS0001: This expression was expected to have type
unit
but here has type
int
Why does the compiler expect 'unit' instead of int ?
It might worth adding that this is not just a property of if
. F# is an expression-based language meaning that pretty much every piece of code (aside from type declarations and a few exceptions) is an expression that evaluates to some result. In fact, F# does not call if
the if statement, but an if expression.
This means that you can use if
in unexpected places. For example, this might be useful:
x/2 + (if x%2=0 then 0 else 1)
As already explained by Garry, if you omit else
, then the expression still needs to return something - if the result was to be an int
, then it would not really make sense (which number should the compiler pick?), so it requires that the result is of type unit
, which is a special type representing "no result".
The unit
type is also the result of all imperative functions (e.g. printf
) or of all expressions that do not logically return any value (assignment or e.g. loop). This means that if you write:
if x > 0 then printfn "Big!"
... then the expression is well-typed, because printfn "Big!"
has a return type unit
and the implicitly added else
branch also returns unit
. You can create a value of type unit
directly by hand (the type has exactly one value), so the above actually corresponds to:
if x > 0 then printfn "Big!" else ()
From the C# perspective, it makes more sense to read if .. then .. else
as the conditional operator:
x/2 + (x%2 == 0 ? 0 : 1)