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