Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Простое определение функции напоминает следующее:
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#.
Пример
Описание
Следующий код содержит все примеры в этом разделе.
Код
// ** 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