Använda funktioner i F#
En enkel funktionsdefinition liknar följande:
let f x = x + 1
I föregående exempel är f
funktionsnamnet , argumentet är x
, som har typen int
, funktionstexten är x + 1
och returvärdet är av typen int
.
En definierande egenskap för F# är att funktioner har förstklassig status. Du kan göra med en funktion vad du kan göra med värden för de andra inbyggda typerna, med en jämförbar grad av ansträngning.
Du kan ge namn på funktionsvärden.
Du kan lagra funktioner i datastrukturer, till exempel i en lista.
Du kan skicka en funktion som ett argument i ett funktionsanrop.
Du kan returnera en funktion från ett funktionsanrop.
Ge värdet ett namn
Om en funktion är ett förstklassigt värde måste du kunna namnge den, precis som du kan namnge heltal, strängar och andra inbyggda typer. Detta kallas i funktionell programmeringslitteratur för att binda en identifierare till ett värde. F# använder let
bindningar för att binda namn till värden: let <identifier> = <value>
. Följande kod visar två exempel.
// Integer and string.
let num = 10
let str = "F#"
Du kan namnge en funktion lika enkelt. I följande exempel definieras en funktion med namnet squareIt
genom att binda identifieraren squareIt
till lambda-uttrycket fun n -> n * n
. Funktionen squareIt
har en parameter, n
, och returnerar kvadraten för parametern.
let squareIt = fun n -> n * n
F# ger följande mer koncisa syntax för att uppnå samma resultat med mindre skrivning.
let squareIt2 n = n * n
Exemplen som följer använder främst det första formatet, , let <function-name> = <lambda-expression>
för att betona likheterna mellan deklarationen av funktioner och deklarationen av andra typer av värden. Men alla namngivna funktioner kan också skrivas med den koncisa syntaxen. Några av exemplen är skrivna på båda sätten.
Lagra värdet i en datastruktur
Ett förstklassigt värde kan lagras i en datastruktur. Följande kod visar exempel som lagrar värden i listor och i tupplar.
// 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 )
För att verifiera att ett funktionsnamn som lagras i en tuppeln faktiskt utvärderas till en funktion använder fst
följande exempel operatorerna och snd
för att extrahera det första och andra elementet från tuppeln funAndArgTuple
. Det första elementet i tuppeln är squareIt
och det andra elementet är num
. Identifieraren num
är i ett tidigare exempel bunden till heltal 10, ett giltigt argument för squareIt
funktionen. Det andra uttrycket tillämpar det första elementet i tuppeln på det andra elementet i tuppeln: 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))
På samma sätt kan precis som identifierare num
och heltal 10 användas omväxlande, så kan identifieraren squareIt
och lambda-uttrycket 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))
Skicka värdet som ett argument
Om ett värde har förstklassig status på ett språk kan du skicka det som ett argument till en funktion. Det är till exempel vanligt att skicka heltal och strängar som argument. Följande kod visar heltal och strängar som skickas som argument i 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)
Om funktioner har förstklassig status måste du kunna skicka dem som argument på samma sätt. Kom ihåg att detta är den första egenskapen för funktioner i högre ordning.
I följande exempel har funktionen applyIt
två parametrar och op
arg
. Om du skickar in en funktion som har en parameter för op
och ett lämpligt argument för funktionen till arg
returnerar funktionen resultatet av att arg
tillämpa på op
. I följande exempel skickas både funktionsargumentet och heltalsargumentet på samma sätt med hjälp av deras namn.
// 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)
Möjligheten att skicka en funktion som ett argument till en annan funktion ligger till grund för vanliga abstraktioner i funktionella programmeringsspråk, till exempel kart- eller filteråtgärder. En kartåtgärd är till exempel en funktion med högre ordning som samlar in beräkningen som delas av funktioner som går igenom en lista, gör något med varje element och sedan returnerar en lista över resultaten. Du kanske vill öka varje element i en lista med heltal, eller att kvadratera varje element, eller ändra varje element i en lista med strängar till versaler. Den felbenägna delen av beräkningen är den rekursiva process som går igenom listan och skapar en lista över de resultat som ska returneras. Den delen samlas in i mappningsfunktionen. Allt du behöver skriva för ett visst program är den funktion som du vill använda för varje listelement individuellt (lägga till, kvart, ändra skiftläge). Den funktionen skickas som ett argument till mappningsfunktionen, precis som squareIt
den skickas till applyIt
i föregående exempel.
F# innehåller kartmetoder för de flesta samlingstyper, inklusive listor, matriser och sekvenser. I följande exempel används listor. Syntax: 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
Mer information finns i Listor.
Returnera värdet från ett funktionsanrop
Om en funktion har förstklassig status på ett språk måste du slutligen kunna returnera den som värdet för ett funktionsanrop, precis som du returnerar andra typer, till exempel heltal och strängar.
Följande funktion anropar retur heltal och visar dem.
// Function doubleIt is defined in a previous example.
//let doubleIt = fun n -> 2 * n
System.Console.WriteLine(doubleIt 3)
System.Console.WriteLine(squareIt 4)
Följande funktionsanrop returnerar en sträng.
// str is defined in a previous section.
//let str = "F#"
let lowercase = str.ToLower()
Följande funktionsanrop, deklarerat infogat, returnerar ett booleskt värde. Värdet som visas är True
.
System.Console.WriteLine((fun n -> n % 2 = 1) 15)
Möjligheten att returnera en funktion som värdet för ett funktionsanrop är den andra egenskapen för funktioner med högre ordning. I följande exempel checkFor
definieras som en funktion som tar ett argument, item
, och returnerar en ny funktion som dess värde. Den returnerade funktionen tar en lista som argument, lst
och söker item
efter i lst
. Om item
finns returnerar true
funktionen . Om item
inte finns returnerar false
funktionen . Precis som i föregående avsnitt använder följande kod en tillhandahållen listfunktion, List.exists, för att söka i listan.
let checkFor item =
let functionToReturn = fun lst ->
List.exists (fun a -> a = item) lst
functionToReturn
Följande kod använder checkFor
för att skapa en ny funktion som tar ett argument, en lista och söker efter 7 i listan.
// 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)
I följande exempel används förstklassig status för funktioner i F# för att deklarera en funktion, compose
, som returnerar en sammansättning med två funktionsargument.
// 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
Kommentar
En ännu kortare version finns i följande avsnitt, "Curryfunktioner".
Följande kod skickar två funktioner som argument till compose
, som båda har ett enda argument av samma typ. Returvärdet är en ny funktion som är en sammansättning av de två funktionsargumenten.
// 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)
Kommentar
F# innehåller två operatorer och <<
>>
, som består av funktioner. Är till let squareAndDouble = compose doubleIt squareIt
exempel let squareAndDouble2 = doubleIt << squareIt
likvärdigt med i föregående exempel.
Följande exempel på hur du returnerar en funktion som värdet för ett funktionsanrop skapar ett enkelt gissningsspel. Om du vill skapa ett spel anropar makeGame
du med det värde som du vill att någon ska gissa skickas in för target
. Returvärdet från funktionen makeGame
är en funktion som tar ett argument (gissningen) och rapporterar om gissningen är korrekt.
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
Följande kod anropar makeGame
och skickar värdet 7
för target
. Identifieraren playGame
är bunden till det returnerade lambda-uttrycket. playGame
Därför är en funktion som tar som ett argument ett värde för 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!
Curryfunktioner
Många av exemplen i föregående avsnitt kan skrivas mer kortfattat genom att dra nytta av implicit currying i F#-funktionsdeklarationer. Currying är en process som omvandlar en funktion som har mer än en parameter till en serie inbäddade funktioner, som var och en har en enda parameter. I F# är funktioner som har mer än en parameter i sig. Från föregående avsnitt kan till exempel compose
skrivas enligt följande koncisa format, med tre parametrar.
let compose4 op1 op2 n = op1 (op2 n)
Resultatet är dock en funktion av en parameter som returnerar en funktion av en parameter som i sin tur returnerar en annan funktion av en parameter, som visas i compose4curried
.
let compose4curried =
fun op1 ->
fun op2 ->
fun n -> op1 (op2 n)
Du kan komma åt den här funktionen på flera sätt. Vart och ett av följande exempel returnerar och visar 18. Du kan ersätta compose4
med compose4curried
i något av exemplen.
// 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)
Om du vill kontrollera att funktionen fortfarande fungerar som den gjorde tidigare provar du de ursprungliga testfallen igen.
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)
Kommentar
Du kan begränsa currying genom att omsluta parametrar i tupplar. Mer information finns i "Parametermönster" i Parametrar och argument.
I följande exempel används implicit currying för att skriva en kortare version av makeGame
. Informationen om hur makeGame
konstruktioner och returnerar game
funktionen är mindre explicit i det här formatet, men du kan kontrollera med hjälp av de ursprungliga testfallen att resultatet är detsamma.
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'
Mer information om currying finns i "Partiell tillämpning av argument" i Functions.
Identifierare och funktionsdefinition är utbytbara
Variabelnamnet num
i föregående exempel utvärderas till heltal 10 och det är ingen överraskning att där num
är giltigt är 10 också giltigt. Detsamma gäller för funktionsidentifierare och deras värden: överallt där namnet på funktionen kan användas kan lambda-uttrycket som den är bunden till användas.
I följande exempel definieras en Boolean
funktion med namnet isNegative
, och sedan används namnet på funktionen och definitionen av funktionen utbytbart. De följande tre exemplen returnerar och visar 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)
Om du vill ta det ett steg längre ersätter du värdet som applyIt
är bundet till för applyIt
.
System.Console.WriteLine((fun op arg -> op arg) (fun n -> n < 0) 10)
Funktioner är förstklassiga värden i F#
Exemplen i föregående avsnitt visar att funktioner i F# uppfyller kriterierna för att vara förstklassiga värden i F#:
- Du kan binda en identifierare till en funktionsdefinition.
let squareIt = fun n -> n * n
- Du kan lagra en funktion i en datastruktur.
let funTuple2 = ( BMICalculator, fun n -> n * n )
- Du kan skicka en funktion som ett argument.
let increments = List.map (fun n -> n + 1) [ 1; 2; 3; 4; 5; 6; 7 ]
- Du kan returnera en funktion som värdet för ett funktionsanrop.
let checkFor item =
let functionToReturn = fun lst ->
List.exists (fun a -> a = item) lst
functionToReturn
Mer information om F# finns i språkreferensen för F#.
Exempel
beskrivning
Följande kod innehåller alla exempel i det här avsnittet.
Code
// ** 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