Использование функций в F #

Простое Определение функции выглядит следующим образом:

let f x = x + 1

В предыдущем примере f является именем функции, x — аргументом, имеющим тип int, x + 1 является телом функции, а возвращаемое значение имеет тип int.

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

  • Можно указать имена значений функций.

  • Функции можно хранить в структурах данных, например в списке.

  • Функцию можно передать в качестве аргумента в вызове функции.

  • Функцию можно вернуть из вызова функции.

Присвоить значение имени

Если функция является значением первого класса, необходимо иметь возможность присвоить ей имя, точно так же, как целые числа, строки и другие встроенные типы. В литературе по функциональному программированию это называется привязкой идентификатора к значению. F # использует привязки для привязки имен к значениям: let <identifier> = <value> . В следующем коде показаны два примера.

// Integer and string.
let num = 10
let str = "F#"

Вы можете легко присвоить имя функции. В следующем примере определяется функция с именем squareIt путем привязки идентификатора squareIt к squareItfun n -> n * n . Функция squareIt имеет один параметр, n и возвращает квадрат этого параметра.

let squareIt = fun n -> n * n

F # предоставляет следующий более краткий синтаксис для достижения того же результата с меньшей типизацией.

let squareIt2 n = n * n

В приведенных ниже примерах используется первый стиль, let <function-name> = <lambda-expression> чтобы подчеркнуть сходство между объявлением функций и объявлением других типов значений. Однако все именованные функции также можно записать с помощью краткого синтаксиса. Некоторые примеры написаны обоими способами.

Сохранение значения в структуре данных

Значение первого класса может храниться в структуре данных. В следующем коде показаны примеры хранения значений в списках и кортежах.

// Lists.

// Storing integers and strings.
let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]
let stringList = [ "one"; "two"; "three" ]

// You cannot mix types in a list. The following declaration causes a
// type-mismatch compiler error.
//let failedList = [ 5; "six" ]

// In F#, functions can be stored in a list, as long as the functions
// have the same signature.

// Function doubleIt has the same signature as squareIt, declared previously.
//let squareIt = fun n -> n * n
let doubleIt = fun n -> 2 * n

// Functions squareIt and doubleIt can be stored together in a list.
let funList = [ squareIt; doubleIt ]

// Function squareIt cannot be stored in a list together with a function
// that has a different signature, such as the following body mass
// index (BMI) calculator.
let BMICalculator = fun ht wt ->
                    (float wt / float (squareIt ht)) * 703.0

// The following expression causes a type-mismatch compiler error.
//let failedFunList = [ squareIt; BMICalculator ]


// Tuples.

// Integers and strings.
let integerTuple = ( 1, -7 )
let stringTuple = ( "one", "two", "three" )

// A tuple does not require its elements to be of the same type.
let mixedTuple = ( 1, "two", 3.3 )

// Similarly, function elements in tuples can have different signatures.
let funTuple = ( squareIt, BMICalculator )

// Functions can be mixed with integers, strings, and other types in
// a tuple. Identifier num was declared previously.
//let num = 10
let moreMixedTuple = ( num, "two", 3.3, squareIt )

Чтобы убедиться, что имя функции, сохраненное в кортеже, фактически выполняет вычисление функции, в следующем примере используются fst операторы и snd для извлечения первого и второго элементов из кортежа funAndArgTuple . Первый элемент в кортеже имеет squareIt значение, а второй элемент — num . Идентификатор num привязывается в предыдущем примере к целому 10, допустимому аргументу для squareIt функции. Второе выражение применяет первый элемент кортежа ко второму элементу в кортеже: squareIt num .

// You can pull a function out of a tuple and apply it. Both squareIt and num
// were defined previously.
let funAndArgTuple = (squareIt, num)

// The following expression applies squareIt to num, returns 100, and
// then displays 100.
System.Console.WriteLine((fst funAndArgTuple)(snd funAndArgTuple))

Точно так же, как идентификатор num и целое число 10, можно использовать взаимозаменяемость, поэтому может быть идентификатором squareIt и лямбда-выражением fun n -> n * n .

// Make a tuple of values instead of identifiers.
let funAndArgTuple2 = ((fun n -> n * n), 10)

// The following expression applies a squaring function to 10, returns
// 100, and then displays 100.
System.Console.WriteLine((fst funAndArgTuple2)(snd funAndArgTuple2))

Передать значение в качестве аргумента

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

// An integer is passed to squareIt. Both squareIt and num are defined in
// previous examples.
//let num = 10
//let squareIt = fun n -> n * n
System.Console.WriteLine(squareIt num)

// String.
// Function repeatString concatenates a string with itself.
let repeatString = fun s -> s + s

// A string is passed to repeatString. HelloHello is returned and displayed.
let greeting = "Hello"
System.Console.WriteLine(repeatString greeting)

Если функции имеют состояние первого класса, необходимо иметь возможность передавать их как аргументы аналогичным образом. Помните, что это первая характеристика функций высшего порядка.

В следующем примере функция applyIt имеет два параметра: op и arg . Если вы отправляете в функцию, имеющую один параметр для op , и соответствующий аргумент функции arg , функция возвращает результат применения op функции к arg . В следующем примере аргументы функции и целочисленный аргумент отправляются одинаковым образом с использованием их имен.

// Define the function, again using lambda expression syntax.
let applyIt = fun op arg -> op arg

// Send squareIt for the function, op, and num for the argument you want to
// apply squareIt to, arg. Both squareIt and num are defined in previous
// examples. The result returned and displayed is 100.
System.Console.WriteLine(applyIt squareIt num)

// The following expression shows the concise syntax for the previous function
// definition.
let applyIt2 op arg = op arg
// The following line also displays 100.
System.Console.WriteLine(applyIt2 squareIt num)

Возможность отправки функции в качестве аргумента в другую функцию зависит от общих абстракций в языках функционального программирования, таких как операции Map или Filter. Операция Map, например, — это функция более высокого порядка, которая захватывает вычисления, совместно используемые функциями, которые пошагово проходят по списку, выполняют какие-либо действия с каждым элементом, а затем возвращают список результатов. Может потребоваться увеличить каждый элемент в списке целых чисел или квадратный каждый элемент или изменить каждый элемент в списке строк на верхний. Подверженная ошибкам часть вычислений является рекурсивным процессом, который проходит по списку и создает список возвращаемых результатов. Эта часть захватывается функцией сопоставления. Все, что необходимо написать для конкретного приложения, — это функция, которую необходимо применить к каждому элементу списка по отдельности (Добавление, возведение в изменяемый регистр). Эта функция отправляется в качестве аргумента функции сопоставления, так же как squareItapplyIt и в предыдущем примере.

F # предоставляет методы Map для большинства типов коллекций, включая списки, массивыи последовательности. В следующих примерах используются списки. Синтаксис: List.map <the function> <the list>.

// List integerList was defined previously:
//let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]

// You can send the function argument by name, if an appropriate function
// is available. The following expression uses squareIt.
let squareAll = List.map squareIt integerList

// The following line displays [1; 4; 9; 16; 25; 36; 49]
printfn "%A" squareAll

// Or you can define the action to apply to each list element inline.
// For example, no function that tests for even integers has been defined,
// so the following expression defines the appropriate function inline.
// The function returns true if n is even; otherwise it returns false.
let evenOrNot = List.map (fun n -> n % 2 = 0) integerList

// The following line displays [false; true; false; true; false; true; false]
printfn "%A" evenOrNot

Дополнительные сведения см. в разделе списки.

Возврат значения из вызова функции

Наконец, если функция имеет состояние первого класса в языке, необходимо иметь возможность возвращать его как значение вызова функции, как и другие типы, такие как целые числа и строки.

Следующие вызовы функции возвращают целые числа и отображают их.

// Function doubleIt is defined in a previous example.
//let doubleIt = fun n -> 2 * n
System.Console.WriteLine(doubleIt 3)
System.Console.WriteLine(squareIt 4)

Следующий вызов функции возвращает строку.

// str is defined in a previous section.
//let str = "F#"
let lowercase = str.ToLower()

Следующий вызов функции, объявленный встроенным, возвращает логическое значение. Отображаемое значение — True .

System.Console.WriteLine((fun n -> n % 2 = 1) 15)

Возможность возвращать функцию в качестве значения вызова функции — это вторая характеристика функций более высокого порядка. В следующем примере checkFor определяется как функция, принимающая один аргумент, item и возвращающая в качестве значения новую функцию. Возвращаемая функция принимает список в качестве аргумента, lst и выполняет поиск item в lst . Если item имеется, функция возвращает true . Если item параметр не указан, функция возвращает false значение. Как и в предыдущем разделе, следующий код использует предоставленную функцию списка List. Existsдля поиска в списке.

let checkFor item =
    let functionToReturn = fun lst ->
                           List.exists (fun a -> a = item) lst
    functionToReturn

Следующий код использует checkFor для создания новой функции, которая принимает один аргумент, список и выполняет поиск 7 в списке.

// integerList and stringList were defined earlier.
//let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]
//let stringList = [ "one"; "two"; "three" ]

// The returned function is given the name checkFor7.
let checkFor7 = checkFor 7

// The result displayed when checkFor7 is applied to integerList is True.
System.Console.WriteLine(checkFor7 integerList)

// The following code repeats the process for "seven" in stringList.
let checkForSeven = checkFor "seven"

// The result displayed is False.
System.Console.WriteLine(checkForSeven stringList)

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

// Function compose takes two arguments. Each argument is a function
// that takes one argument of the same type. The following declaration
// uses lambda expresson syntax.
let compose =
    fun op1 op2 ->
        fun n ->
            op1 (op2 n)

// To clarify what you are returning, use a nested let expression:
let compose2 =
    fun op1 op2 ->
        // Use a let expression to build the function that will be returned.
        let funToReturn = fun n ->
                            op1 (op2 n)
        // Then just return it.
        funToReturn

// Or, integrating the more concise syntax:
let compose3 op1 op2 =
    let funToReturn = fun n ->
                        op1 (op2 n)
    funToReturn

Примечание

Более короткая версия см. в следующем разделе "каррированных функции".

Следующий код отправляет две функции в качестве аргументов в compose , оба из которых принимают один аргумент того же типа. Возвращаемое значение — это новая функция, которая представляет собой композицию двух аргументов функции.

// Functions squareIt and doubleIt were defined in a previous example.
let doubleAndSquare = compose squareIt doubleIt
// The following expression doubles 3, squares 6, and returns and
// displays 36.
System.Console.WriteLine(doubleAndSquare 3)

let squareAndDouble = compose doubleIt squareIt
// The following expression squares 3, doubles 9, returns 18, and
// then displays 18.
System.Console.WriteLine(squareAndDouble 3)

Примечание

F # предоставляет два оператора, << и >> , которые образуют функции. Например, let squareAndDouble2 = doubleIt << squareIt эквивалентен let squareAndDouble = compose doubleIt squareIt в предыдущем примере.

Следующий пример возврата функции в качестве значения вызова функции создает простую игру подбора. Чтобы создать игру, вызовите метод makeGame с тем значением, в target котором вы хотите угадать. Возвращаемое значение функции makeGame — это функция, которая принимает один аргумент (Guess) и сообщает, верно ли предположение.

let makeGame target =
    // Build a lambda expression that is the function that plays the game.
    let game = fun guess ->
                   if guess = target then
                      System.Console.WriteLine("You win!")
                   else
                      System.Console.WriteLine("Wrong. Try again.")
    // Now just return it.
    game

Следующий код вызывает метод makeGame , отправляя значение 7 для target . Идентификатор playGame привязан к возвращенному лямбда-выражению. Таким образом, playGame представляет собой функцию, принимающую в качестве одного аргумента значение для guess .

let playGame = makeGame 7
// Send in some guesses.
playGame 2
playGame 9
playGame 7

// Output:
// Wrong. Try again.
// Wrong. Try again.
// You win!

// The following game specifies a character instead of an integer for target.
let alphaGame = makeGame 'q'
alphaGame 'c'
alphaGame 'r'
alphaGame 'j'
alphaGame 'q'

// Output:
// Wrong. Try again.
// Wrong. Try again.
// Wrong. Try again.
// You win!

Каррированных функции

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

let compose4 op1 op2 n = op1 (op2 n)

Однако результатом является функция одного параметра, возвращающая функцию одного параметра, которая, в свою очередь, возвращает другую функцию одного параметра, как показано в compose4curried .

let compose4curried =
    fun op1 ->
        fun op2 ->
            fun n -> op1 (op2 n)

Доступ к этой функции можно получить несколькими способами. Каждый из следующих примеров возвращает и отображает 18. В любом из примеров можно заменить compose4 на compose4curried .

// Access one layer at a time.
System.Console.WriteLine(((compose4 doubleIt) squareIt) 3)

// Access as in the original compose examples, sending arguments for
// op1 and op2, then applying the resulting function to a value.
System.Console.WriteLine((compose4 doubleIt squareIt) 3)

// Access by sending all three arguments at the same time.
System.Console.WriteLine(compose4 doubleIt squareIt 3)

Чтобы убедиться, что функция все еще работает, как и раньше, попробуйте повторить исходные тестовые случаи.

let doubleAndSquare4 = compose4 squareIt doubleIt
// The following expression returns and displays 36.
System.Console.WriteLine(doubleAndSquare4 3)

let squareAndDouble4 = compose4 doubleIt squareIt
// The following expression returns and displays 18.
System.Console.WriteLine(squareAndDouble4 3)

Примечание

Можно ограничить карринг, заключив параметры в кортежи. Дополнительные сведения см. в разделе "Шаблоны параметров" раздела Параметры и аргументы.

В следующем примере используется неявное карринг для записи более короткой версии makeGame . Сведения о том, как makeGame конструкции и возвращают game функцию, менее явны в этом формате, но можно проверить с помощью исходных тестовых случаев, в которых результат совпадает.

let makeGame2 target guess =
    if guess = target then
       System.Console.WriteLine("You win!")
    else
       System.Console.WriteLine("Wrong. Try again.")

let playGame2 = makeGame2 7
playGame2 2
playGame2 9
playGame2 7

let alphaGame2 = makeGame2 'q'
alphaGame2 'c'
alphaGame2 'r'
alphaGame2 'j'
alphaGame2 'q'

Дополнительные сведения о карринг см. в разделе "частичное применение аргументов" в функциях.

Идентификатор и определение функции взаимозаменяемы

Имя num переменной в предыдущих примерах вычисляется как целое число 10, и это не удивительно, что num допустимо, 10 также является допустимым. То же самое касается идентификаторов функций и их значений: где можно использовать имя функции, можно использовать лямбда-выражение, к которому она привязана.

В следующем примере определяется Boolean функция с именем isNegative , а затем используется имя функции и определение взаимозаменяемой функции. В следующих трех примерах возвращаются и отображаются False .

let isNegative = fun n -> n < 0

// This example uses the names of the function argument and the integer
// argument. Identifier num is defined in a previous example.
//let num = 10
System.Console.WriteLine(applyIt isNegative num)

// This example substitutes the value that num is bound to for num, and the
// value that isNegative is bound to for isNegative.
System.Console.WriteLine(applyIt (fun n -> n < 0) 10)

Чтобы сделать это на один шаг дальше, замените значение, applyIt привязанное к для applyIt .

System.Console.WriteLine((fun op arg -> op arg) (fun n -> n < 0)  10)

Функции — это First-Class значений в F #

В примерах, приведенных в предыдущих разделах, показано, что функции в F # удовлетворяют критериям для значений первого класса в F #:

  • Идентификатор можно привязать к определению функции.
let squareIt = fun n -> n * n
  • Функцию можно сохранить в структуре данных.
let funTuple2 = ( BMICalculator, fun n -> n * n )
  • Функцию можно передать в качестве аргумента.
let increments = List.map (fun n -> n + 1) [ 1; 2; 3; 4; 5; 6; 7 ]
  • Функцию можно вернуть в качестве значения вызова функции.
let checkFor item =
    let functionToReturn = fun lst ->
                           List.exists (fun a -> a = item) lst
    functionToReturn

Дополнительные сведения о F # см. в справочнике по языку f #.

Пример

Описание

Следующий код содержит все примеры, приведенные в этом разделе.

Код

// ** GIVE THE VALUE A NAME **


// Integer and string.
let num = 10
let str = "F#"



let squareIt = fun n -> n * n



let squareIt2 n = n * n



// ** STORE THE VALUE IN A DATA STRUCTURE **


// Lists.

// Storing integers and strings.
let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]
let stringList = [ "one"; "two"; "three" ]

// You cannot mix types in a list. The following declaration causes a
// type-mismatch compiler error.
//let failedList = [ 5; "six" ]

// In F#, functions can be stored in a list, as long as the functions
// have the same signature.

// Function doubleIt has the same signature as squareIt, declared previously.
//let squareIt = fun n -> n * n
let doubleIt = fun n -> 2 * n

// Functions squareIt and doubleIt can be stored together in a list.
let funList = [ squareIt; doubleIt ]

// Function squareIt cannot be stored in a list together with a function
// that has a different signature, such as the following body mass
// index (BMI) calculator.
let BMICalculator = fun ht wt ->
                    (float wt / float (squareIt ht)) * 703.0

// The following expression causes a type-mismatch compiler error.
//let failedFunList = [ squareIt; BMICalculator ]


// Tuples.

// Integers and strings.
let integerTuple = ( 1, -7 )
let stringTuple = ( "one", "two", "three" )

// A tuple does not require its elements to be of the same type.
let mixedTuple = ( 1, "two", 3.3 )

// Similarly, function elements in tuples can have different signatures.
let funTuple = ( squareIt, BMICalculator )

// Functions can be mixed with integers, strings, and other types in
// a tuple. Identifier num was declared previously.
//let num = 10
let moreMixedTuple = ( num, "two", 3.3, squareIt )



// You can pull a function out of a tuple and apply it. Both squareIt and num
// were defined previously.
let funAndArgTuple = (squareIt, num)

// The following expression applies squareIt to num, returns 100, and
// then displays 100.
System.Console.WriteLine((fst funAndArgTuple)(snd funAndArgTuple))



// Make a list of values instead of identifiers.
let funAndArgTuple2 = ((fun n -> n * n), 10)

// The following expression applies a squaring function to 10, returns
// 100, and then displays 100.
System.Console.WriteLine((fst funAndArgTuple2)(snd funAndArgTuple2))



// ** PASS THE VALUE AS AN ARGUMENT **


// An integer is passed to squareIt. Both squareIt and num are defined in
// previous examples.
//let num = 10
//let squareIt = fun n -> n * n
System.Console.WriteLine(squareIt num)

// String.
// Function repeatString concatenates a string with itself.
let repeatString = fun s -> s + s

// A string is passed to repeatString. HelloHello is returned and displayed.
let greeting = "Hello"
System.Console.WriteLine(repeatString greeting)



// Define the function, again using lambda expression syntax.
let applyIt = fun op arg -> op arg

// Send squareIt for the function, op, and num for the argument you want to
// apply squareIt to, arg. Both squareIt and num are defined in previous
// examples. The result returned and displayed is 100.
System.Console.WriteLine(applyIt squareIt num)

// The following expression shows the concise syntax for the previous function
// definition.
let applyIt2 op arg = op arg
// The following line also displays 100.
System.Console.WriteLine(applyIt2 squareIt num)



// List integerList was defined previously:
//let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]

// You can send the function argument by name, if an appropriate function
// is available. The following expression uses squareIt.
let squareAll = List.map squareIt integerList

// The following line displays [1; 4; 9; 16; 25; 36; 49]
printfn "%A" squareAll

// Or you can define the action to apply to each list element inline.
// For example, no function that tests for even integers has been defined,
// so the following expression defines the appropriate function inline.
// The function returns true if n is even; otherwise it returns false.
let evenOrNot = List.map (fun n -> n % 2 = 0) integerList

// The following line displays [false; true; false; true; false; true; false]
printfn "%A" evenOrNot



// ** RETURN THE VALUE FROM A FUNCTION CALL **


// Function doubleIt is defined in a previous example.
//let doubleIt = fun n -> 2 * n
System.Console.WriteLine(doubleIt 3)
System.Console.WriteLine(squareIt 4)


// The following function call returns a string:

// str is defined in a previous section.
//let str = "F#"
let lowercase = str.ToLower()



System.Console.WriteLine((fun n -> n % 2 = 1) 15)



let checkFor item =
    let functionToReturn = fun lst ->
                           List.exists (fun a -> a = item) lst
    functionToReturn



// integerList and stringList were defined earlier.
//let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]
//let stringList = [ "one"; "two"; "three" ]

// The returned function is given the name checkFor7.
let checkFor7 = checkFor 7

// The result displayed when checkFor7 is applied to integerList is True.
System.Console.WriteLine(checkFor7 integerList)

// The following code repeats the process for "seven" in stringList.
let checkForSeven = checkFor "seven"

// The result displayed is False.
System.Console.WriteLine(checkForSeven stringList)



// Function compose takes two arguments. Each argument is a function
// that takes one argument of the same type. The following declaration
// uses lambda expresson syntax.
let compose =
    fun op1 op2 ->
        fun n ->
            op1 (op2 n)

// To clarify what you are returning, use a nested let expression:
let compose2 =
    fun op1 op2 ->
        // Use a let expression to build the function that will be returned.
        let funToReturn = fun n ->
                            op1 (op2 n)
        // Then just return it.
        funToReturn

// Or, integrating the more concise syntax:
let compose3 op1 op2 =
    let funToReturn = fun n ->
                        op1 (op2 n)
    funToReturn



// Functions squareIt and doubleIt were defined in a previous example.
let doubleAndSquare = compose squareIt doubleIt
// The following expression doubles 3, squares 6, and returns and
// displays 36.
System.Console.WriteLine(doubleAndSquare 3)

let squareAndDouble = compose doubleIt squareIt
// The following expression squares 3, doubles 9, returns 18, and
// then displays 18.
System.Console.WriteLine(squareAndDouble 3)



let makeGame target =
    // Build a lambda expression that is the function that plays the game.
    let game = fun guess ->
                   if guess = target then
                      System.Console.WriteLine("You win!")
                   else
                      System.Console.WriteLine("Wrong. Try again.")
    // Now just return it.
    game



let playGame = makeGame 7
// Send in some guesses.
playGame 2
playGame 9
playGame 7

// Output:
// Wrong. Try again.
// Wrong. Try again.
// You win!

// The following game specifies a character instead of an integer for target.
let alphaGame = makeGame 'q'
alphaGame 'c'
alphaGame 'r'
alphaGame 'j'
alphaGame 'q'

// Output:
// Wrong. Try again.
// Wrong. Try again.
// Wrong. Try again.
// You win!



// ** CURRIED FUNCTIONS **


let compose4 op1 op2 n = op1 (op2 n)



let compose4curried =
    fun op1 ->
        fun op2 ->
            fun n -> op1 (op2 n)



// Access one layer at a time.
System.Console.WriteLine(((compose4 doubleIt) squareIt) 3)

// Access as in the original compose examples, sending arguments for
// op1 and op2, then applying the resulting function to a value.
System.Console.WriteLine((compose4 doubleIt squareIt) 3)

// Access by sending all three arguments at the same time.
System.Console.WriteLine(compose4 doubleIt squareIt 3)



let doubleAndSquare4 = compose4 squareIt doubleIt
// The following expression returns and displays 36.
System.Console.WriteLine(doubleAndSquare4 3)

let squareAndDouble4 = compose4 doubleIt squareIt
// The following expression returns and displays 18.
System.Console.WriteLine(squareAndDouble4 3)



let makeGame2 target guess =
    if guess = target then
       System.Console.WriteLine("You win!")
    else
       System.Console.WriteLine("Wrong. Try again.")

let playGame2 = makeGame2 7
playGame2 2
playGame2 9
playGame2 7

let alphaGame2 = makeGame2 'q'
alphaGame2 'c'
alphaGame2 'r'
alphaGame2 'j'
alphaGame2 'q'



// ** IDENTIFIER AND FUNCTION DEFINITION ARE INTERCHANGEABLE **


let isNegative = fun n -> n < 0

// This example uses the names of the function argument and the integer
// argument. Identifier num is defined in a previous example.
//let num = 10
System.Console.WriteLine(applyIt isNegative num)

// This example substitutes the value that num is bound to for num, and the
// value that isNegative is bound to for isNegative.
System.Console.WriteLine(applyIt (fun n -> n < 0) 10)



System.Console.WriteLine((fun op arg -> op arg) (fun n -> n < 0)  10)



// ** FUNCTIONS ARE FIRST-CLASS VALUES IN F# **

//let squareIt = fun n -> n * n


let funTuple2 = ( BMICalculator, fun n -> n * n )



let increments = List.map (fun n -> n + 1) [ 1; 2; 3; 4; 5; 6; 7 ]


//let checkFor item =
//    let functionToReturn = fun lst ->
//                           List.exists (fun a -> a = item) lst
//    functionToReturn

См. также раздел