F # - ฟังก์ชั่น
ใน F # ฟังก์ชันจะทำงานเหมือนกับชนิดข้อมูล คุณสามารถประกาศและใช้ฟังก์ชันในลักษณะเดียวกับตัวแปรอื่น ๆ
เนื่องจากสามารถใช้ฟังก์ชันเหมือนกับตัวแปรอื่น ๆ คุณจึงสามารถ -
- สร้างฟังก์ชันโดยใช้ชื่อและเชื่อมโยงชื่อนั้นกับประเภท
- กำหนดค่า
- ทำการคำนวณค่านั้น
- ส่งผ่านเป็นพารามิเตอร์ไปยังฟังก์ชันอื่นหรือรูทีนย่อย
- ส่งคืนฟังก์ชันเป็นผลลัพธ์ของฟังก์ชันอื่น
การกำหนดฟังก์ชัน
ฟังก์ชันถูกกำหนดโดยใช้ letคำสำคัญ. นิยามฟังก์ชันมีไวยากรณ์ต่อไปนี้ -
let [inline] function-name parameter-list [ : return-type ]
= function-body
ที่ไหน
function-name เป็นตัวระบุที่แสดงถึงฟังก์ชัน
parameter-listให้รายการพารามิเตอร์ที่คั่นด้วยช่องว่าง คุณยังสามารถระบุประเภทที่ชัดเจนสำหรับแต่ละพารามิเตอร์และหากไม่ได้ระบุคอมไพลเลอร์มีแนวโน้มที่จะอนุมานจากเนื้อหาของฟังก์ชัน (เช่นตัวแปร)
function-bodyประกอบด้วยนิพจน์หรือนิพจน์ประกอบที่ประกอบด้วยนิพจน์จำนวนหนึ่ง นิพจน์สุดท้ายในเนื้อหาฟังก์ชันคือค่าที่ส่งคืน
return-typeเป็นเครื่องหมายจุดคู่ตามด้วยชนิดและเป็นทางเลือก หากไม่ได้ระบุชนิดการส่งคืนคอมไพลเลอร์จะกำหนดจากนิพจน์สุดท้ายในเนื้อหาฟังก์ชัน
พารามิเตอร์ของฟังก์ชัน
คุณแสดงชื่อของพารามิเตอร์ต่อจากชื่อฟังก์ชัน คุณสามารถระบุประเภทของพารามิเตอร์ ประเภทของพารามิเตอร์ควรเป็นไปตามชื่อของพารามิเตอร์ที่คั่นด้วยเครื่องหมายจุดคู่
หากไม่ได้ระบุประเภทพารามิเตอร์จะถูกอนุมานโดยคอมไพลเลอร์
ตัวอย่างเช่น -
let doubleIt (x : int) = 2 * x
เรียกใช้ฟังก์ชัน
ฟังก์ชันถูกเรียกโดยระบุชื่อฟังก์ชันตามด้วยช่องว่างจากนั้นอาร์กิวเมนต์ใด ๆ ที่คั่นด้วยช่องว่าง
ตัวอย่างเช่น -
let vol = cylinderVolume 3.0 5.0
โปรแกรมต่อไปนี้แสดงให้เห็นถึงแนวคิด
ตัวอย่าง 1
โปรแกรมต่อไปนี้จะคำนวณปริมาตรของทรงกระบอกเมื่อกำหนดรัศมีและความยาวเป็นพารามิเตอร์
// the function calculates the volume of
// a cylinder with radius and length as parameters
let cylinderVolume radius length : float =
// function body
let pi = 3.14159
length * pi * radius * radius
let vol = cylinderVolume 3.0 5.0
printfn " Volume: %g " vol
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Volume: 141.372
ตัวอย่าง 2
โปรแกรมต่อไปนี้ส่งคืนค่าที่ใหญ่กว่าของพารามิเตอร์ที่กำหนดสองตัว -
// the function returns the larger value between two
// arguments
let max num1 num2 : int32 =
// function body
if(num1>num2)then
num1
else
num2
let res = max 39 52
printfn " Max Value: %d " res
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Max Value: 52
ตัวอย่างที่ 3
let doubleIt (x : int) = 2 * x
printfn "Double 19: %d" ( doubleIt(19))
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Double 19: 38
ฟังก์ชันแบบเรียกซ้ำ
ฟังก์ชันเรียกซ้ำคือฟังก์ชันที่เรียกตัวเอง
คุณกำหนดการเรียกซ้ำโดยใช้ let rec การรวมคำหลัก
ไวยากรณ์สำหรับการกำหนดฟังก์ชันเรียกซ้ำคือ -
//Recursive function definition
let rec function-name parameter-list = recursive-function-body
ตัวอย่างเช่น -
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
ตัวอย่าง 1
โปรแกรมต่อไปนี้ส่งคืน Fibonacci 1 ถึง 10 -
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
for i = 1 to 10 do
printfn "Fibonacci %d: %d" i (fib i)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Fibonacci 1: 1
Fibonacci 2: 2
Fibonacci 3: 3
Fibonacci 4: 5
Fibonacci 5: 8
Fibonacci 6: 13
Fibonacci 7: 21
Fibonacci 8: 34
Fibonacci 9: 55
Fibonacci 10: 89
ตัวอย่าง 2
โปรแกรมต่อไปนี้ส่งคืนแฟกทอเรียล 8 -
open System
let rec fact x =
if x < 1 then 1
else x * fact (x - 1)
Console.WriteLine(fact 8)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
40320
สัญลักษณ์ลูกศรใน F #
F # รายงานเกี่ยวกับประเภทข้อมูลในฟังก์ชันและค่าโดยใช้สัญลักษณ์ลูกศรที่ถูกล่ามโซ่ ให้เรายกตัวอย่างฟังก์ชันที่รับอินพุตintหนึ่งรายการและส่งคืนสตริง ในสัญกรณ์ลูกศรเขียนเป็น -
int -> string
ประเภทข้อมูลอ่านจากซ้ายไปขวา
ให้เราใช้ฟังก์ชันสมมุติฐานอื่นที่รับอินพุตข้อมูล int สองรายการและส่งคืนสตริง
let mydivfunction x y = (x / y).ToString();;
F # รายงานประเภทข้อมูลโดยใช้สัญลักษณ์ลูกศรที่ถูกล่ามโซ่เป็น -
val mydivfunction : x:int -> y:int -> string
ประเภทการส่งคืนแสดงโดยชนิดข้อมูลขวาสุดในสัญกรณ์ลูกศรที่ถูกล่ามโซ่
ตัวอย่างเพิ่มเติม -
สัญกรณ์ | ความหมาย |
---|---|
ลอย→ลอย→ลอย | ฟังก์ชั่นใช้เวลาสองลอยปัจจัยการผลิตกลับมาอีกลอย |
int →สตริง→ลอย | ฟังก์ชั่นใช้เวลาintและสตริงป้อนข้อมูลส่งกลับลอย |
แลมบ์ดานิพจน์
ก lambda expression เป็นฟังก์ชันที่ไม่มีชื่อ
ให้เรายกตัวอย่างของสองฟังก์ชัน -
let applyFunction ( f: int -> int -> int) x y = f x y
let mul x y = x * y
let res = applyFunction mul 5 7
printfn "%d" res
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
35
ตอนนี้ในตัวอย่างข้างต้นถ้าแทนที่จะกำหนดฟังก์ชันmulเราสามารถใช้นิพจน์แลมบ์ดาเป็น -
let applyFunction ( f: int -> int -> int) x y = f x y
let res = applyFunction (fun x y -> x * y ) 5 7
printfn "%d" res
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
35
องค์ประกอบของฟังก์ชันและการวางท่อ
ใน F # ฟังก์ชันหนึ่งสามารถประกอบจากฟังก์ชันอื่นได้
ตัวอย่างต่อไปนี้แสดงองค์ประกอบของฟังก์ชันชื่อ f จากสองฟังก์ชัน function1 และ function2 -
let function1 x = x + 1
let function2 x = x * 5
let f = function1 >> function2
let res = f 10
printfn "%d" res
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
55
F # ยังมีคุณสมบัติที่เรียกว่า pipelining of functions. การวางท่อช่วยให้การเรียกใช้ฟังก์ชันถูกผูกเข้าด้วยกันเป็นการดำเนินการต่อเนื่องกัน
ตัวอย่างต่อไปนี้แสดงให้เห็นว่า -
let function1 x = x + 1
let function2 x = x * 5
let res = 10 |> function1 |> function2
printfn "%d" res
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
55