F#功能

2018-12-15 10:50 更新

在F#中,函數(shù)的工作就像數(shù)據(jù)類型。可以聲明和任何其他變量相同的方式使用的功能。

由于函數(shù)可以像任何其他變量可以使用,你可以 -

  • 創(chuàng)建一個函數(shù),一個名字和名稱與類型相關聯(lián)。
  • 它分配一個值。
  • 執(zhí)行該值的一些計算。
  • 通過它作為參數(shù)傳遞給另一個函數(shù)或子例程。
  • 返回的函數(shù)作為另一個函數(shù)的結果。

定義一個函數(shù)

功能通過使用let關鍵字定義。函數(shù)定義的語法如下 -

let [inline] function-name parameter-list [ : return-type ]
= function-body
  • 函數(shù)名是表示函數(shù)的標識符。

  • 參數(shù)列表給出了用空格分隔參數(shù)列表。您還可以指定一個顯式類型的每一個參數(shù),如果沒有指定編譯器傾向于從函數(shù)體(如變量)推斷出結論。

  • 函數(shù)體由一個表達式,或者由若干表達式的化合物的表情。函數(shù)體中最后一個表達式返回值。

  • 返回型是冒號后跟一個類型并且是可選的。如果沒有指定返回類型,則編譯器在函數(shù)體中最后一個表達式?jīng)Q定了它。

一個函數(shù)參數(shù)

你函數(shù)名之后列出的參數(shù)名稱??梢灾付▍?shù)的類型。參數(shù)類型應遵循由冒號分隔參數(shù)的名稱。

如果沒有指定參數(shù)類型,它是由編譯器推斷。

例如 -

let doubleIt (x : int) = 2 * x

調(diào)用一個函數(shù)

一個函數(shù)可以通過指定函數(shù)名稱,后跟一個空格,然后用空格分隔任何參數(shù)調(diào)用。

例如 -

let vol = cylinderVolume 3.0 5.0

下面的程序演示的概念。

例1

以下程序計算時的半徑和長度給定為參數(shù)的圓柱體的體積。

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 -

Volume: 141.372

例2

下列程序返回的兩個給定參數(shù)的較大值 -

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 -

Max Value: 52

例3

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 -

Double 19: 38

遞歸函數(shù)

遞歸函數(shù)是自稱的功能。

您可以定義使用let rec關鍵字組合遞歸。

語法定義遞歸函數(shù)是 

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

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

以下程序返回factorial 8

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 -

40320

箭頭符號

F#使用鏈式箭頭符號報告函數(shù)和值中的數(shù)據(jù)類型。 讓我們以一個函數(shù)為例,輸入int,并返回一個字符串。在代碼里,它被寫成 
int -> string

數(shù)據(jù)類型讀左到右。

讓我們假設另外一個功能,它有兩個int數(shù)據(jù)輸入,并返回一個字符串。

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

F#報告使用鏈式箭頭符號作為數(shù)據(jù)類型 -

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

返回類型由鏈式箭頭符號最右邊的數(shù)據(jù)類型來表示。

更多的例子 

符號含義
float → float → float該函數(shù)需要兩個輸入,返回另一個。
int → string → float該函數(shù)接受ainting astringinput,返回float。

Lambda表達式

lambda表達式是匿名函數(shù)。

讓我們以兩個函數(shù)作為例子

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 -

35

現(xiàn)在在上面的例子中,而不是定義函數(shù),我們可以使用lambda表達式 

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 -

35

函數(shù)組合和流水線

在F#中,一個功能可以從其他的功能組成。

下面的示例顯示了一個名為女,來自兩個函數(shù)功能1和功能2功能組成 -

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

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 -

55

F#還提供了一個叫做pipelining of functions的功能流水線中,函數(shù)調(diào)用作為連續(xù)操作進行鏈接在一起。

下面的例子說明 

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

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

當你編譯和執(zhí)行程序,它產(chǎn)生以下輸出 

55
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號