F # - Chức năng

Trong F #, các hàm hoạt động giống như kiểu dữ liệu. Bạn có thể khai báo và sử dụng một hàm theo cách tương tự như bất kỳ biến nào khác.

Vì các hàm có thể được sử dụng giống như bất kỳ biến nào khác, bạn có thể -

  • Tạo một hàm, với một tên và liên kết tên đó với một kiểu.
  • Gán cho nó một giá trị.
  • Thực hiện một số phép tính trên giá trị đó.
  • Chuyển nó dưới dạng một tham số cho một hàm hoặc quy trình con khác.
  • Trả về một hàm là kết quả của một hàm khác.

Xác định một chức năng

Các hàm được xác định bằng cách sử dụng lettừ khóa. Định nghĩa hàm có cú pháp sau:

let [inline] function-name parameter-list [ : return-type ]
   = function-body

Ở đâu,

  • function-name là một định danh đại diện cho chức năng.

  • parameter-listđưa ra danh sách các tham số được phân tách bằng dấu cách. Bạn cũng có thể chỉ định một kiểu rõ ràng cho từng tham số và nếu không chỉ định trình biên dịch có xu hướng suy ra nó từ thân hàm (như các biến).

  • function-bodybao gồm một biểu thức hoặc một biểu thức ghép bao gồm một số biểu thức. Biểu thức cuối cùng trong thân hàm là giá trị trả về.

  • return-typelà dấu hai chấm theo sau bởi một loại và là tùy chọn. Nếu kiểu trả về không được chỉ định, thì trình biên dịch xác định nó từ biểu thức cuối cùng trong thân hàm.

Các tham số của một hàm

Bạn liệt kê tên các tham số ngay sau tên hàm. Bạn có thể chỉ định loại tham số. Loại tham số phải theo sau tên của tham số được phân tách bằng dấu hai chấm.

Nếu không có kiểu tham số nào được chỉ định, nó được trình biên dịch suy ra.

Ví dụ -

let doubleIt (x : int) = 2 * x

Gọi một hàm

Một hàm được gọi bằng cách chỉ định tên hàm theo sau là dấu cách và sau đó là bất kỳ đối số nào được phân tách bằng dấu cách.

Ví dụ -

let vol = cylinderVolume 3.0 5.0

Các chương trình sau đây minh họa các khái niệm.

ví dụ 1

Chương trình sau đây tính thể tích của một hình trụ khi bán kính và chiều dài được cho dưới dạng tham số

// 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

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Volume: 141.372

Ví dụ 2

Chương trình sau đây trả về giá trị lớn hơn của hai tham số đã cho:

// 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

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Max Value: 52

Ví dụ 3

let doubleIt (x : int) = 2 * x
printfn "Double 19: %d" ( doubleIt(19))

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Double 19: 38

Các hàm đệ quy

Các hàm đệ quy là các hàm gọi chính nó.

Bạn xác định một đệ quy bằng cách sử dụng let rec kết hợp từ khóa.

Cú pháp để xác định một hàm đệ quy là:

//Recursive function definition
let rec function-name parameter-list = recursive-function-body

Ví dụ -

let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)

ví dụ 1

Chương trình sau trả về Fibonacci 1 đến 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)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

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

Ví dụ 2

Chương trình sau đây trả về giai thừa 8:

open System
let rec fact x =
   if x < 1 then 1
   else x * fact (x - 1)
Console.WriteLine(fact 8)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

40320

Ký hiệu mũi tên trong F #

F # báo cáo về kiểu dữ liệu trong các hàm và giá trị, sử dụng ký hiệu mũi tên theo chuỗi. Chúng ta hãy lấy một ví dụ về một hàm nhận một đầu vào int và trả về một chuỗi. Trong ký hiệu mũi tên, nó được viết là -

int -> string

Các kiểu dữ liệu được đọc từ trái sang phải.

Hãy để chúng tôi thực hiện một hàm giả thuyết khác nhận hai đầu vào dữ liệu int và trả về một chuỗi.

let mydivfunction x y = (x / y).ToString();;

F # báo cáo kiểu dữ liệu sử dụng ký hiệu mũi tên chuỗi là -

val mydivfunction : x:int -> y:int -> string

Kiểu trả về được biểu thị bằng kiểu dữ liệu ngoài cùng bên phải trong ký hiệu mũi tên chuỗi.

Một số ví dụ khác -

Ký hiệu Ý nghĩa
float → float → float Hàm nhận hai đầu vào float , trả về một float khác .
int → string → float Chức năng mất một int và một chuỗi đầu vào, lợi nhuận một phao .

Biểu thức Lambda

A lambda expression là một chức năng không được đặt tên.

Hãy để chúng tôi lấy một ví dụ về hai chức năng -

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

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

35

Bây giờ trong ví dụ trên, nếu thay vì định nghĩa hàm mul, chúng ta có thể sử dụng biểu thức lambda như sau:

let applyFunction ( f: int -> int -> int) x y = f x y
let res = applyFunction (fun x y -> x * y ) 5 7
printfn "%d" res

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

35

Thành phần chức năng và Pipelining

Trong F #, một hàm có thể được kết hợp từ các hàm khác.

Ví dụ sau đây cho thấy thành phần của một hàm có tên f, từ hai hàm function1 và function2 -

let function1 x = x + 1
let function2 x = x * 5

let f = function1 >> function2
let res = f 10
printfn "%d" res

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

55

F # cũng cung cấp một tính năng được gọi là pipelining of functions. Pipelining cho phép các lệnh gọi hàm được xâu chuỗi lại với nhau như các hoạt động liên tiếp.

Ví dụ sau đây cho thấy rằng -

let function1 x = x + 1
let function2 x = x * 5

let res = 10 |> function1 |> function2
printfn "%d" res

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

55