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

Простое определение функции напоминает следующее:

let f x = x + 1

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

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

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

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

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

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

Присвойте значению имя

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

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

Вы можете назвать функцию так же легко. В следующем примере определяется функция, именуемая squareIt путем привязки идентификатора squareIt к лямбда-выражениюfun 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 имеет два параметра и oparg. Если вы отправляете функцию с одним параметром op и соответствующим аргументом для функции arg, функция возвращает результат применения oparg. В следующем примере аргумент функции и целый аргумент отправляются одинаково, используя их имена.

// 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)

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

F# предоставляет методы сопоставления для большинства типов коллекций, включая списки, массивы и последовательности. В следующих примерах используются списки. Синтаксис: 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 expression 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 , которая принимает один аргумент (угадывание) и сообщает, является ли угадывание правильным.

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)

Функции — это значения первого класса в 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#.

Пример

Description

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

Код

// ** 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 expression 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

См. также