Чтобы немного расширить правильные комментарии Mankarse, синтаксис F # для определения значений и функций выглядит очень похоже, поэтому их легко спутать.
Это значение:
let sum = 42
Это функция:
let addThree x = x + 3
И значения, и функции могут иметь после них блоков , а не только отдельные строки:
let sumWithSideEffects =
// This will only be evaluated once
printfn "Side effect happens here"
42
let addThree x =
// This will run every time you call the function
let result = x + 3
printfn "Added three to %d and got %d" x result
result
A let
объявление, которое просто объявляет имя, является значением.Значения оцениваются только один раз, поэтому любые побочные эффекты в значении произойдут только один раз.Точно , когда они происходят, точно не определяется спецификацией языка, поэтому вы не можете рассчитывать, когда произойдут побочные эффекты.С другой стороны, функции оцениваются каждый раз, когда вызывается функция.
Теперь, когда у вас есть функция, которая не принимает параметров, как вы ее объявляете?Ну, вы объявляете это, давая ему параметр, но параметр, который не имеет значения .В частности, вы заявляете, что он принимает параметр типа unit
.Тип unit
является специальным типом в F #.Это в основном соответствует пустому кортежу и записывается как ()
.
Подумайте о типе пустого кортежа на минуту.Если у вас есть кортеж из двух bool
значений, сколько возможных значений может иметь этот кортеж?Четыре: это может быть (false, false)
, или (false, true)
, или (true, false)
, или (true, true)
.Если у вас есть кортеж всего one bool
, он может иметь два значения: (true)
или (false)
.Если у вас есть кортеж ноль значений (любого типа: bool, int, string, не имеет значения), то есть только одно возможное значение, которое он может иметь: ()
, пустой кортеж.И так как это тип только с одним возможным значением, именно поэтому он называется типом unit
.
Так что если вам нужна функция, а не значение, но эта функция не должна принимать какие-либо значимые параметры, вы определяете это так:
let myFunction () =
printfn "I'm being called purely for the side effects"
Обратите внимание, как я помещаю пробел между именем функции и параметром unit
.На самом деле у вас нет , чтобы иметь это место - совершенно законно писать let myFunction() = ...
- но я хочу, чтобы вы увидели, что ()
- это не просто синтаксис объявления функции, это фактическое значение фактического типа.Это различие становится важным, когда вы начинаете делать более сложные вещи с помощью функций, поэтому я хочу, чтобы вы прояснили это сейчас.
Кстати, обычно в объявлении функции у вас будет имя параметра, а не значение, нотип unit
обрабатывается специально: поскольку существует только одно возможное значение unit
, вы уже знаете, с каким значением будет вызываться ваша функция, поэтому вам не нужно в любом случае присваивать это имя.Таким образом, F # позволяет вам объявить функцию с типом ввода unit
, просто указав ()
в списке параметров, вместо того, чтобы заставлять вас выбирать имя, которое вы никогда не будете использовать в теле функции.
Я надеюсь, что это прояснит для вас.