F'de işlevleri kullanma#
Basit bir işlev tanımı aşağıdakine benzer:
let f x = x + 1
Önceki örnekte işlev adı , bağımsız değişkeni türünde, işlev gövdesi ise ve f x dönüş değeri int x + 1 int türündedir.
F# özelliğinin bir tanımlama özelliği, işlevlerin birinci sınıf durumuna sahip olduğudır. bir işlevle, diğer yerleşik türlerin değerleriyle ne yapasınız, ne olursa olsun, benzer bir çaba derecesiyle bunu yapabiliriz.
İşlev değerleri adları veebilirsiniz.
İşlevleri bir listede olduğu gibi veri yapılarında depoabilirsiniz.
İşlevi bir işlev çağrısında bağımsız değişken olarak geçesiniz.
bir işlev çağrısından işlev getirsiniz.
Değere Bir Ad Ver
Bir işlev birinci sınıf bir değerse, tamsayıları, dizeleri ve diğer yerleşik türleri gibi adlayayabileceksiniz. Bu, işlevsel programlama literatürde bir tanımlayıcıyı değere bağlama olarak adlandırılır. F#, let adları değerlere bağlamak için bağlamaları kullanır: let <identifier> = <value> . Aşağıdaki kodda iki örnek verilmiştir.
// Integer and string.
let num = 10
let str = "F#"
Bir işlevi kolayca adlayabilirsiniz. Aşağıdaki örnek, tanımlayıcıyı squareIt lambda ifadesine squareIt bağladığı adlı bir işlevi tanımlar. fun n -> n * n İşlevin squareIt bir parametresi vardır ve bu n parametrenin karesi döndürür.
let squareIt = fun n -> n * n
F# daha az yazma ile aynı sonucu elde etmek için aşağıdaki daha kısa söz dizimi sağlar.
let squareIt2 n = n * n
Aşağıdaki örneklerde çoğunlukla ilk stil olan , işlev bildirimi ile diğer değer türlerinin bildirimi arasındaki let <function-name> = <lambda-expression> benzerlikleri vurgulamak için kullanılır. Ancak, tüm adlandırılmış işlevler kısa söz dizimi ile de yazabilirsiniz. Bazı örnekler her iki şekilde de yazılır.
Değeri Bir Veri Yapısında Depolama
Birinci sınıf değer bir veri yapısında depolanmış olabilir. Aşağıdaki kod, değerleri listelerde ve veri dizilerinde depoleyen örnekleri gösterir.
// 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 )
Bir kayıtta depolanan işlev adının aslında bir işlev olarak değerlendirilip değerlendirilmesini doğrulamak için, aşağıdaki örnekte ve işleçleri kullanarak kayıttan birinci ve fst snd ikinci öğeleri funAndArgTuple ayıklar. Tuple'daki ilk öğe, squareIt ikinci öğe ise num olur. Tanımlayıcı, önceki bir örnekte işlev için geçerli bir bağımsız değişken olan num 10 tamsayıya squareIt bağlandı. İkinci ifade, tuple'daki ilk öğeyi, tuple'daki ikinci öğeye uygular: 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))
Benzer şekilde, aynı tanımlayıcı ve tamsayı 10 birbirinin yerine kullanılabilir; böylece tanımlayıcı num ve squareIt lambda ifadesi fun n -> n * n kullanılabilir.
// 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))
Değeri Bağımsız Değişken Olarak Geçme
Bir değer, bir dilde birinci sınıf durumuna sahipse, bunu bir işleve bağımsız değişken olarak geçesiniz. Örneğin, tamsayıları ve dizeleri bağımsız değişken olarak yaygın olarak geçer. Aşağıdaki kod F# içinde bağımsız değişken olarak geçirilen tamsayıları ve dizeleri gösterir.
// 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)
İşlevler birinci sınıf durumuna sahipse, bunları aynı şekilde bağımsız değişken olarak geçebilirsiniz. Bunun yüksek sıralı işlevlerin ilk özelliği olduğunu unutmayın.
Aşağıdaki örnekte işlevin applyIt iki parametresi vardır: ve op arg . için bir parametreye ve işlevi için uygun bir bağımsız değişkene sahip bir işlev op arg gönderirsiniz, işlevi için uygulamanın sonucu op arg döndürür. Aşağıdaki örnekte, hem işlev bağımsız değişkeni hem de tamsayı bağımsız değişkeni adları kullanılarak aynı şekilde gönderilir.
// 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)
Bir işlevi başka bir işleve bağımsız değişken olarak gönderme özelliği, eşleme veya filtre işlemleri gibi işlevsel programlama dillerinde yaygın soyutlamaların altında yer almaktadır. Örneğin eşleme işlemi, bir listede adım adım ilerler, her öğeye bir şey yapar ve ardından sonuçların listesini geri alan işlevler tarafından paylaşılan hesaplamayı yakalayan daha yüksek sıralı bir işlevdir. Bir tamsayı listesinde yer alan her öğeyi artırmayı veya her bir öğenin karesini almak ya da dizeler listesinde yer alan her öğeyi büyük harf olarak değiştirmek istemeyebilirsiniz. Hesaplamanın hataya açık bölümü, listede adım adım ilerler ve geri dönmek için sonuçların bir listesini derleme işlemidir. Bu bölüm, eşleme işlevinde yakalanır. Belirli bir uygulama için yazmanız gereken tek şey, her bir liste öğesine tek tek uygulamak istediğiniz işlevdir (ekleme, diska ekleme, büyük/küçük harf değiştirme). Bu işlev, önceki örnekte olduğu gibi eşleme squareIt işlevine bir bağımsız applyIt değişken olarak gönderilir.
F# listeleri, dizileri ve dizileri dahil olmak üzereçoğu koleksiyon türü içineşleme yöntemleri sağlar. Aşağıdaki örneklerde listeler kullanılabilir. Söz dizimi List.map <the function> <the list> şeklindedir.
// 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
Daha fazla bilgi için bkz. Listeler.
İşlev Çağrısından Değer İadeSi
Son olarak, bir işlevin bir dilde birinci sınıf durumu varsa, tamsayılar ve dizeler gibi diğer türleri de döndürür gibi işlev çağrısının değeri olarak bunu da getiresiniz.
Aşağıdaki işlev, tamsayıları döndürür ve görüntüler.
// Function doubleIt is defined in a previous example.
//let doubleIt = fun n -> 2 * n
System.Console.WriteLine(doubleIt 3)
System.Console.WriteLine(squareIt 4)
Aşağıdaki işlev çağrısı bir dize döndürür.
// str is defined in a previous section.
//let str = "F#"
let lowercase = str.ToLower()
Satır içinde bildirilen aşağıdaki işlev çağrısı bir Boole değeri döndürür. Görüntülenen değer: True .
System.Console.WriteLine((fun n -> n % 2 = 1) 15)
bir işlevi işlev çağrısının değeri olarak geri getirebilme özelliği, yüksek sıralı işlevlerin ikinci özelliğidir. Aşağıdaki örnekte, bir bağımsız değişken alan ve değeri olarak yeni bir işlev checkFor item döndüren bir işlev olarak tanımlanır. Döndürülen işlev bağımsız değişkeni olarak bir liste alır lst ve içinde item için aramalar. lst varsa item işlevi true döndürür. yoksa item işlevi false döndürür. Önceki bölümde olduğu gibi, aşağıdaki kod listede arama yapmak için List.existsliste işlevini kullanır.
let checkFor item =
let functionToReturn = fun lst ->
List.exists (fun a -> a = item) lst
functionToReturn
Aşağıdaki kod, bir bağımsız değişken, bir liste alan ve listede 7 için arama checkFor yapılan yeni bir işlev oluşturmak için kullanır.
// 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)
Aşağıdaki örnek, iki işlev bağımsız değişkeninin bir bileşimini döndüren bir işlevi ( ) bildiren F# içinde işlevlerin compose birinci sınıf durumunu kullanır.
// Function compose takes two arguments. Each argument is a function
// that takes one argument of the same type. The following declaration
// uses lambda expresson syntax.
let compose =
fun op1 op2 ->
fun n ->
op1 (op2 n)
// To clarify what you are returning, use a nested let expression:
let compose2 =
fun op1 op2 ->
// Use a let expression to build the function that will be returned.
let funToReturn = fun n ->
op1 (op2 n)
// Then just return it.
funToReturn
// Or, integrating the more concise syntax:
let compose3 op1 op2 =
let funToReturn = fun n ->
op1 (op2 n)
funToReturn
Not
Daha da kısa bir sürüm için aşağıdaki "Curried functions" bölümüne bakın.
Aşağıdaki kod, her ikisi de aynı türde tek bir bağımsız değişken alan iki compose işlevi bağımsız değişken olarak gönderir. Dönüş değeri, iki işlev bağımsız değişkeninin bileşimi olan yeni bir işlevdir.
// 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)
Not
F# işlevleri oluşturan ve << >> olmak için iki işleç sağlar. Örneğin, let squareAndDouble2 = doubleIt << squareIt önceki let squareAndDouble = compose doubleIt squareIt örnekteki ile eşdeğerdir.
Bir işlevi işlev çağrısının değeri olarak döndüren aşağıdaki örnek, basit bir tahmin oyunu oluşturur. Bir oyun oluşturmak için, makeGame birinin için gönderildiğini tahmin etmek istediğiniz değeriyle çağrısı target oluşturun. işlevinden dönüş değeri, bir bağımsız değişken (tahmin) alan ve tahminin doğru olup olmadığını rapor makeGame alan bir işlevdir.
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
Aşağıdaki kod için değerini makeGame göndererek 7 çağrısında target dır. Tanımlayıcı, playGame döndürülen lambda ifadesine bağlı. Bu playGame nedenle, tek bağımsız değişkeni olarak değerini alan bir guess işlevdir.
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 İşlevleri
Önceki bölümdeki örneklerin çoğu, F# işlev bildirimlerini örtülü kurdeleden yararlanarak daha kısa yazabilirsiniz. Currying, birden fazla parametreye sahip olan bir işlevi, her biri tek bir parametreye sahip olan bir dizi katıştırılmış işleve dönüştüren bir işlemdir. F# içinde, birden fazla parametreye sahip işlevler doğal olarak curried'dır. Örneğin, compose önceki bölümden aşağıdaki kısa stilde gösterildiği gibi üç parametreyle yazabilirsiniz.
let compose4 op1 op2 n = op1 (op2 n)
Ancak sonuç, içinde gösterildiği gibi bir parametrenin başka bir işlevini döndüren bir parametrenin işlevini döndüren bir parametrenin compose4curried işlevidir.
let compose4curried =
fun op1 ->
fun op2 ->
fun n -> op1 (op2 n)
Bu işleve çeşitli yollarla erişebilirsiniz. Aşağıdaki örneklerin her biri 18 döndürür ve görüntüler. Örneklerinin compose4 herhangi compose4curried birsinde yerine değiştirilebilir.
// 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)
İşlevin daha önce olduğu gibi çalıştığını doğrulamak için özgün test çalışmalarını yeniden deneyin.
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)
Not
Parametreleriuples içine alan parametrelerle currying'i kısıtlarsiniz. Daha fazla bilgi için Parametreler ve Bağımsız Değişkenler'de "Parametre Desenleri" 'ne bakın.
Aşağıdaki örnek, daha kısa bir sürümü yazmak için örtük currying makeGame kullanır. İşlevi oluşturma ve döndürür ile ilgili ayrıntılar bu biçimde daha az açıktır, ancak özgün test çalışmalarını kullanarak makeGame game sonucun aynı olduğunu doğruabilirsiniz.
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'
Currying hakkında daha fazla bilgi için İşlevler'de "Bağımsız Değişkenlerin Kısmi Uygulaması" 'ne bakın.
Tanımlayıcı ve İşlev Tanımı Birbirinin Yerine Kullanılabilir
Önceki örneklerde yer alan değişken adı 10 tamsayısı olarak değerlendirilir ve burada geçerli olan 10 değerinin de geçerli num num olması şaşırtıcı değildir. İşlev tanımlayıcıları ve değerleri için de aynı durum geçerli olur: işlevin adı her yerde, bağlı olduğu lambda ifadesi kullanılabilir.
Aşağıdaki örnek adlı bir işlevi tanımlar ve ardından işlevin adını ve işlevinin tanımını Boolean isNegative birbirinin yerine kullanır. Sonraki üç örneğin hepsi geri döner ve False görüntüler.
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)
Bunu bir adım daha ileri götürecek şekilde, applyIt değerine bağlı olan değerinin yerine applyIt geçin.
System.Console.WriteLine((fun op arg -> op arg) (fun n -> n < 0) 10)
İşlevler F'First-Class DeğerleriDir#
Önceki bölümlerde yer alan örnekler, F# içinde işlevlerin F# içinde birinci sınıf değerler olma ölçütlerini karşılar:
- Bir tanımlayıcıyı işlev tanımına b bağlama.
let squareIt = fun n -> n * n
- Bir işlevi bir veri yapısında saklayabilirsiniz.
let funTuple2 = ( BMICalculator, fun n -> n * n )
- Bir işlevi bağımsız değişken olarak geçirebilirsiniz.
let increments = List.map (fun n -> n + 1) [ 1; 2; 3; 4; 5; 6; 7 ]
- İşlev çağrısının değeri olarak bir işlev döndürebilirsiniz.
let checkFor item =
let functionToReturn = fun lst ->
List.exists (fun a -> a = item) lst
functionToReturn
F # hakkında daha fazla bilgi için f # dil başvurusunabakın.
Örnek
Description
Aşağıdaki kod, bu konudaki tüm örnekleri içerir.
Kod
// ** GIVE THE VALUE A NAME **
// Integer and string.
let num = 10
let str = "F#"
let squareIt = fun n -> n * n
let squareIt2 n = n * n
// ** STORE THE VALUE IN A DATA STRUCTURE **
// Lists.
// Storing integers and strings.
let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]
let stringList = [ "one"; "two"; "three" ]
// You cannot mix types in a list. The following declaration causes a
// type-mismatch compiler error.
//let failedList = [ 5; "six" ]
// In F#, functions can be stored in a list, as long as the functions
// have the same signature.
// Function doubleIt has the same signature as squareIt, declared previously.
//let squareIt = fun n -> n * n
let doubleIt = fun n -> 2 * n
// Functions squareIt and doubleIt can be stored together in a list.
let funList = [ squareIt; doubleIt ]
// Function squareIt cannot be stored in a list together with a function
// that has a different signature, such as the following body mass
// index (BMI) calculator.
let BMICalculator = fun ht wt ->
(float wt / float (squareIt ht)) * 703.0
// The following expression causes a type-mismatch compiler error.
//let failedFunList = [ squareIt; BMICalculator ]
// Tuples.
// Integers and strings.
let integerTuple = ( 1, -7 )
let stringTuple = ( "one", "two", "three" )
// A tuple does not require its elements to be of the same type.
let mixedTuple = ( 1, "two", 3.3 )
// Similarly, function elements in tuples can have different signatures.
let funTuple = ( squareIt, BMICalculator )
// Functions can be mixed with integers, strings, and other types in
// a tuple. Identifier num was declared previously.
//let num = 10
let moreMixedTuple = ( num, "two", 3.3, squareIt )
// You can pull a function out of a tuple and apply it. Both squareIt and num
// were defined previously.
let funAndArgTuple = (squareIt, num)
// The following expression applies squareIt to num, returns 100, and
// then displays 100.
System.Console.WriteLine((fst funAndArgTuple)(snd funAndArgTuple))
// Make a list of values instead of identifiers.
let funAndArgTuple2 = ((fun n -> n * n), 10)
// The following expression applies a squaring function to 10, returns
// 100, and then displays 100.
System.Console.WriteLine((fst funAndArgTuple2)(snd funAndArgTuple2))
// ** PASS THE VALUE AS AN ARGUMENT **
// An integer is passed to squareIt. Both squareIt and num are defined in
// previous examples.
//let num = 10
//let squareIt = fun n -> n * n
System.Console.WriteLine(squareIt num)
// String.
// Function repeatString concatenates a string with itself.
let repeatString = fun s -> s + s
// A string is passed to repeatString. HelloHello is returned and displayed.
let greeting = "Hello"
System.Console.WriteLine(repeatString greeting)
// Define the function, again using lambda expression syntax.
let applyIt = fun op arg -> op arg
// Send squareIt for the function, op, and num for the argument you want to
// apply squareIt to, arg. Both squareIt and num are defined in previous
// examples. The result returned and displayed is 100.
System.Console.WriteLine(applyIt squareIt num)
// The following expression shows the concise syntax for the previous function
// definition.
let applyIt2 op arg = op arg
// The following line also displays 100.
System.Console.WriteLine(applyIt2 squareIt num)
// List integerList was defined previously:
//let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]
// You can send the function argument by name, if an appropriate function
// is available. The following expression uses squareIt.
let squareAll = List.map squareIt integerList
// The following line displays [1; 4; 9; 16; 25; 36; 49]
printfn "%A" squareAll
// Or you can define the action to apply to each list element inline.
// For example, no function that tests for even integers has been defined,
// so the following expression defines the appropriate function inline.
// The function returns true if n is even; otherwise it returns false.
let evenOrNot = List.map (fun n -> n % 2 = 0) integerList
// The following line displays [false; true; false; true; false; true; false]
printfn "%A" evenOrNot
// ** RETURN THE VALUE FROM A FUNCTION CALL **
// Function doubleIt is defined in a previous example.
//let doubleIt = fun n -> 2 * n
System.Console.WriteLine(doubleIt 3)
System.Console.WriteLine(squareIt 4)
// The following function call returns a string:
// str is defined in a previous section.
//let str = "F#"
let lowercase = str.ToLower()
System.Console.WriteLine((fun n -> n % 2 = 1) 15)
let checkFor item =
let functionToReturn = fun lst ->
List.exists (fun a -> a = item) lst
functionToReturn
// integerList and stringList were defined earlier.
//let integerList = [ 1; 2; 3; 4; 5; 6; 7 ]
//let stringList = [ "one"; "two"; "three" ]
// The returned function is given the name checkFor7.
let checkFor7 = checkFor 7
// The result displayed when checkFor7 is applied to integerList is True.
System.Console.WriteLine(checkFor7 integerList)
// The following code repeats the process for "seven" in stringList.
let checkForSeven = checkFor "seven"
// The result displayed is False.
System.Console.WriteLine(checkForSeven stringList)
// Function compose takes two arguments. Each argument is a function
// that takes one argument of the same type. The following declaration
// uses lambda expresson syntax.
let compose =
fun op1 op2 ->
fun n ->
op1 (op2 n)
// To clarify what you are returning, use a nested let expression:
let compose2 =
fun op1 op2 ->
// Use a let expression to build the function that will be returned.
let funToReturn = fun n ->
op1 (op2 n)
// Then just return it.
funToReturn
// Or, integrating the more concise syntax:
let compose3 op1 op2 =
let funToReturn = fun n ->
op1 (op2 n)
funToReturn
// Functions squareIt and doubleIt were defined in a previous example.
let doubleAndSquare = compose squareIt doubleIt
// The following expression doubles 3, squares 6, and returns and
// displays 36.
System.Console.WriteLine(doubleAndSquare 3)
let squareAndDouble = compose doubleIt squareIt
// The following expression squares 3, doubles 9, returns 18, and
// then displays 18.
System.Console.WriteLine(squareAndDouble 3)
let makeGame target =
// Build a lambda expression that is the function that plays the game.
let game = fun guess ->
if guess = target then
System.Console.WriteLine("You win!")
else
System.Console.WriteLine("Wrong. Try again.")
// Now just return it.
game
let playGame = makeGame 7
// Send in some guesses.
playGame 2
playGame 9
playGame 7
// Output:
// Wrong. Try again.
// Wrong. Try again.
// You win!
// The following game specifies a character instead of an integer for target.
let alphaGame = makeGame 'q'
alphaGame 'c'
alphaGame 'r'
alphaGame 'j'
alphaGame 'q'
// Output:
// Wrong. Try again.
// Wrong. Try again.
// Wrong. Try again.
// You win!
// ** CURRIED FUNCTIONS **
let compose4 op1 op2 n = op1 (op2 n)
let compose4curried =
fun op1 ->
fun op2 ->
fun n -> op1 (op2 n)
// Access one layer at a time.
System.Console.WriteLine(((compose4 doubleIt) squareIt) 3)
// Access as in the original compose examples, sending arguments for
// op1 and op2, then applying the resulting function to a value.
System.Console.WriteLine((compose4 doubleIt squareIt) 3)
// Access by sending all three arguments at the same time.
System.Console.WriteLine(compose4 doubleIt squareIt 3)
let doubleAndSquare4 = compose4 squareIt doubleIt
// The following expression returns and displays 36.
System.Console.WriteLine(doubleAndSquare4 3)
let squareAndDouble4 = compose4 doubleIt squareIt
// The following expression returns and displays 18.
System.Console.WriteLine(squareAndDouble4 3)
let makeGame2 target guess =
if guess = target then
System.Console.WriteLine("You win!")
else
System.Console.WriteLine("Wrong. Try again.")
let playGame2 = makeGame2 7
playGame2 2
playGame2 9
playGame2 7
let alphaGame2 = makeGame2 'q'
alphaGame2 'c'
alphaGame2 'r'
alphaGame2 'j'
alphaGame2 'q'
// ** IDENTIFIER AND FUNCTION DEFINITION ARE INTERCHANGEABLE **
let isNegative = fun n -> n < 0
// This example uses the names of the function argument and the integer
// argument. Identifier num is defined in a previous example.
//let num = 10
System.Console.WriteLine(applyIt isNegative num)
// This example substitutes the value that num is bound to for num, and the
// value that isNegative is bound to for isNegative.
System.Console.WriteLine(applyIt (fun n -> n < 0) 10)
System.Console.WriteLine((fun op arg -> op arg) (fun n -> n < 0) 10)
// ** FUNCTIONS ARE FIRST-CLASS VALUES IN F# **
//let squareIt = fun n -> n * n
let funTuple2 = ( BMICalculator, fun n -> n * n )
let increments = List.map (fun n -> n + 1) [ 1; 2; 3; 4; 5; 6; 7 ]
//let checkFor item =
// let functionToReturn = fun lst ->
// List.exists (fun a -> a = item) lst
// functionToReturn