F # условные выражения if ... then..еще возвращаясь блок или ()
условные выражения F#требуют проверки условия, ветви для true и ветви для false. Например:
let x = 
    if ("hello" = null) 
    then true
    else false //error if else branch missing
однако, что-то становится странным, когда unit, иначе () участвует.
let y = 
    if ("hello" = null) 
    then raise <| new ArgumentNullException()
    else () //happy with or without else branch
и просто:
let z = 
    if ("hello" = null) 
    then ()
    else () //happy with or without else branch
почему неelse филиал требуется, когда unit возвращается?
4 ответов
рассмотрим следующий код:
let f a = if a > 5 then true
если вы называете f 10 возвращает true. 
теперь спросите себя: что должно f 2 вернуться? Я знаю, ты скажешь false, но откуда компилятор знает, что? Я имею в виду, это так же вероятно, что вы хотели, чтобы он вернулся true в обоих случаях, не так ли? Или даже, возможно, врезаться в a <= 5 случае, кто знает?
Итак, чтобы программа была "полной" (т. е. содержала инструкции для того, что делать в каждой ситуации), вы всегда должны указать else филиала.
unit, однако,специальные.
возвращение unit означает, что нет значимого возвращаемого значения. По существу unit означает побочный эффект: это означает, что вещь, которая вернула его, должна была произвести некоторый эффект во внешнем мире. Поскольку F# не является чистым языком, такой unit-возвращение вещи довольно вездесущи. Например, отладка logging:
let f x =
    if x < 42 then printfn "Something fishy, x = %d" x
    x + 5
С такими утверждениями нет никакой двусмысленности: всегда известно, что else ветка предназначена для возврата () как хорошо. В конце концов, других значений unit, там? В то же время, всегда добавляем else () в конце было бы очень утомительно и запутанно. Таким образом, в интересах удобства использования компилятор не требует else филиал в этом конкретном случае.
В F# if является выражением, а не утверждением. Каждое выражение должно возвращать значение. А как if и else необходимо вернуть тот же тип значения, потому что F# является строго типизированным языком. Так что, если нет else ветвь, то по умолчанию она имеет тип unit, а если if возвращает значение типаunit, тогда вам нужно иметь else С тем же типом.  
если убрать else из первого фрагмента, это эквивалентно 
let x = 
    if ("hello" = null) 
    then true
    else ()
не typecheck.
почему? Я бы предположил, для совместимости с Программирования OCaml
на
else expr3часть может быть опущена, и в этом случае она по умолчаниюelse (). (7.7.2)
вы можете думать о unit-возвратить if как эквивалент C-like if сообщении в отличие от выражения.
вопрос уже ответил, поэтому я просто собираюсь продолжить свои собственные поверхностные наблюдения
в F# у нас нет операторов и выражений. В F# мы составляем вычисления, используя только выражения. Это хороший вещь.
в C#, где if это утверждение имеет смысл
if(x)
{
  return 1;
}
если x истинно выполнение остановлено, и мы возвращаем вызывающему результат: 1.
в F#, где if выражение это означает, что if должен представлять ценность независимо от того, какая ветвь была взята. Поэтому это имеет мало смысла
if x then 1 // What value should else branch evaluate to?
мы должны указать обе ветви
if x then 1 else 0
как показывают другие ответы, существует особый случай, когда else опущен. The if выражение произведет unit value, самое близкое, что мы получаем к оператору в F#.
 Потому что тип if выражение является единицей ветвь "true" должна иметь тип unit.
if x then ()         // This works
if x then () else () // This works
if x then 1          // This won't work, type mismatch