Итак, давайте немного абстрагируем ваш код:
if a then b
elif x then y
elif p then q
Исходя из этого, компилятор может сказать, что при a = true
результат должен быть b
.Когда a = false
, он должен проверить x
next, а если x = true
, результат должен быть y
.Теперь, если оба значения a
и x
окажутся false
, компилятор знает, что нужно перейти к проверке p
, а если p = true
, то результат будет q
.
Но вот вопрос: каким должен быть результат, когда все три, a
, b
и p
окажутся ложными?
Вы не сказали компилятору, что делать в этомслучай, так что, конечно, он жалуется!
Но почему он так загадочно жалуется?При чем тут unit
?
Это связано с небольшим синтаксическим ослаблением, которое существует в F # для облегчения жизни разработчиков.Видите ли, поскольку F # не является функциональным языком pure , что означает, что он может иметь произвольные побочные эффекты, очень часто эти побочные эффекты не возвращают никакого значимого значения, например printf
, например:
> printf "foo"
it : unit = ()
Функция не имеет ничего хорошего для возврата, но должен быть какой-то тип возврата, и для этого есть специальный тип - unit
.Это специальный тип, который имеет ровно одно значение, поэтому он ничего не значит.
Теперь давайте посмотрим, что произойдет, если мне нужно поместить мой вызов printf
в if
: в любой if
обе ветви then
и else
должны иметь один и тот же тип, иначе неясно, каким должен быть тип всего выражения if
.Поэтому, если моя ветка then
содержит printf
, моя ветвь else также должна иметь тип unit
.Поэтому я вынужден всегда помещать туда это бессмысленное приложение:
> if foo then printf "bar" else ()
it : unit = ()
Это раздражает.На самом деле, так досадно, что у языка F # есть особый случай: когда моя ветка then
имеет тип unit
, я могу вообще пропустить ветку else
, и компилятор просто предположит, что я имел в видусказать else ()
:
> if foo then printf "bar"
it : unit = ()
Так вот, что происходит в вашем случае: так как вы пропустили ветку else
, компилятор предполагает, что все ветви then
должны быть типа unit
, но они явно относятся к типу float
, поэтому компилятор жалуется.
Чтобы это исправить, вам нужно предоставить ветку else
.Судя по вашему коду, мне кажется, что вы действительно имели в виду возможные случаи: (1) менее 10, (2) от 10 до 100 и (3) все остальное.Если так, то ветвь «все остальное» должно быть else
:
if Balance < 10.00 then "Balance is low"
elif Balance >= 10.00 && Balance <= 100.00 then "Balance is ok"
else "balance is high"
PS. После того, как вы исправите это, у вас будет похожая проблема в функции test
: дваthen
ветви string
, но else
ветви float