Учебники

F # — Функции

В F # функции работают как типы данных. Вы можете объявить и использовать функцию так же, как и любую другую переменную.

Поскольку функции могут использоваться как любые другие переменные, вы можете —

  • Создайте функцию с именем и свяжите это имя с типом.
  • Назначьте это значение.
  • Выполните некоторые расчеты по этому значению.
  • Передайте его в качестве параметра другой функции или подпрограмме.
  • Вернуть функцию как результат другой функции.

Определение функции

Функции определяются с помощью ключевого слова let . Определение функции имеет следующий синтаксис —

let [inline] function-name parameter-list [ : return-type ]
   = function-body

Куда,

  • имя-функции — это идентификатор, который представляет функцию.

  • Параметр-список дает список параметров, разделенных пробелами. Вы также можете указать явный тип для каждого параметра и, если он не указан, компилятор стремится вывести его из тела функции (например, переменных).

  • function-body состоит из выражения или составного выражения, состоящего из ряда выражений. Последнее выражение в теле функции — это возвращаемое значение.

  • return-type — это двоеточие, за которым следует тип, и является необязательным. Если тип возвращаемого значения не указан, компилятор определяет его по окончательному выражению в теле функции.

имя-функции — это идентификатор, который представляет функцию.

Параметр-список дает список параметров, разделенных пробелами. Вы также можете указать явный тип для каждого параметра и, если он не указан, компилятор стремится вывести его из тела функции (например, переменных).

function-body состоит из выражения или составного выражения, состоящего из ряда выражений. Последнее выражение в теле функции — это возвращаемое значение.

return-type — это двоеточие, за которым следует тип, и является необязательным. Если тип возвращаемого значения не указан, компилятор определяет его по окончательному выражению в теле функции.

Параметры функции

Вы перечисляете имена параметров сразу после имени функции. Вы можете указать тип параметра. Тип параметра должен следовать за именем параметра, разделенным двоеточием.

Если тип параметра не указан, он выводится компилятором.

Например —

let doubleIt (x : int) = 2 * x

Вызов функции

Функция вызывается путем указания имени функции, за которым следует пробел, а затем любые аргументы, разделенные пробелами.

Например —

let vol = cylinderVolume 3.0 5.0

Следующие программы иллюстрируют концепции.

Пример 1

Следующая программа вычисляет объем цилиндра, когда радиус и длина заданы как параметры

Live Demo

// the function calculates the volume of
// a cylinder with radius and length as parameters

let cylinderVolume radius length : float =

   // function body
   let pi = 3.14159
   length * pi * radius * radius

let vol = cylinderVolume 3.0 5.0
printfn " Volume: %g " vol

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

Volume: 141.372

Пример 2

Следующая программа возвращает большее значение двух заданных параметров —

Live Demo

// the function returns the larger value between two
// arguments

let max num1 num2 : int32 =
   // function body
   if(num1>num2)then
      num1
   else
      num2

let res = max 39 52
printfn " Max Value: %d " res

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

Max Value: 52

Пример 3

Live Demo

let doubleIt (x : int) = 2 * x
printfn "Double 19: %d" ( doubleIt(19))

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

Double 19: 38

Рекурсивные функции

Рекурсивные функции — это функции, которые вызывают сами себя.

Вы определяете рекурсив с помощью комбинации ключевых слов let rec .

Синтаксис для определения рекурсивной функции —

//Recursive function definition
let rec function-name parameter-list = recursive-function-body

Например —

let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)

Пример 1

Следующая программа возвращает Фибоначчи от 1 до 10 —

Live Demo

let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
for i = 1 to 10 do
   printfn "Fibonacci %d: %d" i (fib i)

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

Fibonacci 1: 1
Fibonacci 2: 2
Fibonacci 3: 3
Fibonacci 4: 5
Fibonacci 5: 8
Fibonacci 6: 13
Fibonacci 7: 21
Fibonacci 8: 34
Fibonacci 9: 55
Fibonacci 10: 89

Пример 2

Следующая программа возвращает факториал 8 —

Live Demo

open System
let rec fact x =
   if x < 1 then 1
   else x * fact (x - 1)
Console.WriteLine(fact 8)

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

40320

Обозначения стрелок в F #

F # сообщает о типе данных в функциях и значениях, используя цепочку обозначений стрелок. Давайте возьмем пример функции, которая принимает один ввод int и возвращает строку. В обозначении стрелки это написано как —

int -> string

Типы данных читаются слева направо.

Давайте возьмем другую гипотетическую функцию, которая принимает два ввода данных int и возвращает строку.

let mydivfunction x y = (x / y).ToString();;

F # сообщает тип данных, используя цепочку обозначений стрелок как —

val mydivfunction : x:int -> y:int -> string

Тип возвращаемого значения представлен крайним правым типом данных в нотации со стрелками.

Еще несколько примеров —

нотация Имея в виду
плавать → плавать → плавать Функция принимает два входа с плавающей точкой , возвращает еще один с плавающей точкой .
int → string → float Функция принимает int и строковый ввод, возвращает число с плавающей запятой .

Лямбда-выражения

Лямбда-выражение — это безымянная функция.

Давайте возьмем пример двух функций —

Live Demo

let applyFunction ( f: int -> int -> int) x y = f x y
let mul x y = x * y
let res = applyFunction mul 5 7
printfn "%d" res

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

35

Теперь в приведенном выше примере, если бы вместо определения функции mul мы могли бы использовать лямбда-выражения как —

Live Demo

let applyFunction ( f: int -> int -> int) x y = f x y
let res = applyFunction (fun x y -> x * y ) 5 7
printfn "%d" res

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

35

Композиция функций и конвейерная обработка

В F # одна функция может быть составлена ​​из других функций.

В следующем примере показана композиция функции с именем f из двух функций function1 и function2 —

Live Demo

let function1 x = x + 1
let function2 x = x * 5

let f = function1 >> function2
let res = f 10
printfn "%d" res

Когда вы компилируете и запускаете программу, она выдает следующий вывод:

55

F # также предоставляет функцию, называемую конвейерной передачей функций. Конвейерная обработка позволяет объединять вызовы функций как последовательные операции.

Следующий пример показывает, что —

Live Demo

let function1 x = x + 1
let function2 x = x * 5

let res = 10 |> function1 |> function2
printfn "%d" res

Когда вы компилируете и запускаете программу, она выдает следующий вывод: