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