# 函式Functions

## 語法Syntax

// Non-recursive function definition.
let [inline] function-name parameter-list [ : return-type ] = function-body
// Recursive function definition.
let rec function-name parameter-list = recursive-function-body

## 備註Remarks

function-name 表示函式的識別項。The function-name is an identifier that represents the function. parameter-list 由以空格分隔的連續參數所組成。The parameter-list consists of successive parameters that are separated by spaces. 您可以指定每個參數的明確類型，如＜參數＞一節中所述。You can specify an explicit type for each parameter, as described in the Parameters section. 若未指定特定的引數類型，編譯器會嘗試從函式主體推斷類型。If you do not specify a specific argument type, the compiler attempts to infer the type from the function body. function-body 由運算式組成。The function-body consists of an expression. 函式主體通常是由組合運算式組成，其中包含數個會產生最終運算式作為傳回值的運算式。The expression that makes up the function body is typically a compound expression consisting of a number of expressions that culminate in a final expression that is the return value. return-type 是選擇性項目，包含後面接著類型的冒號。The return-type is a colon followed by a type and is optional. 若您沒有明確指定傳回值的類型，則編譯器會從最終運算式判斷傳回型別。If you do not specify the type of the return value explicitly, the compiler determines the return type from the final expression.

let f x = x + 1

## 範圍Scope

let list1 = [ 1; 2; 3]
// Error: duplicate definition.
let list1 = []
let function1 =
let list1 = [1; 2; 3]
let list1 = []
list1

let list1 = [ 1; 2; 3]
let sumPlus x =
// OK: inner list1 hides the outer list1.
let list1 = [1; 5; 10]
x + List.sum list1

### 參數Parameters

let f (x : int) = x + 1

let f x = x + 1

let f x = (x, x)

## 函式主體Function Bodies

// Define a local value pi.
let pi = 3.14159

## 傳回值Return Values

let cylinderVolume radius length : float =
// Define a local value pi.
let pi = 3.14159

let cylinderVolume (radius : float) (length : float) : float

## 呼叫函式Calling a Function

let vol = cylinderVolume 2.0 3.0

## 部分套用引數Partial Application of Arguments

// These define functions that take the length as a remaining
// argument:

let length1 = 30.0
let length2 = 40.0
let smallPipeVol1 = smallPipeVolume length1
let smallPipeVol2 = smallPipeVolume length2
let bigPipeVol1 = bigPipeVolume length1
let bigPipeVol2 = bigPipeVolume length2

## 遞迴函式Recursive Functions

「遞迴函式」 是會自我呼叫的函式。Recursive functions are functions that call themselves. 您必須在 let 關鍵字後面指定 rec 關鍵字來使用遞迴函式。They require that you specify the rec keyword following the let keyword. 請從函式主體中叫用遞迴函式，就像叫用任何函式呼叫一樣。Invoke the recursive function from within the body of the function just as you would invoke any function call. 下列遞迴函式會計算 n 個的斐波上數位。The following recursive function computes the nth Fibonacci number. Fibonacci 數字序列自古聞名，此序列中的每個連續數字都是前兩個數字的總和。The Fibonacci number sequence has been known since antiquity and is a sequence in which each successive number is the sum of the previous two numbers in the sequence.

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

## 函式值Function Values

let apply1 (transform : int -> int ) y = transform y

let increment x = x + 1

let result1 = apply1 increment 100

let apply2 ( f: int -> int -> int) x y = f x y

let mul x y = x * y

let result2 = apply2 mul 10 20

## Lambda 運算式Lambda Expressions

「Lambda 運算式」 是不具名函式。A lambda expression is an unnamed function. 在上述範例中，您可以使用 Lambda 運算式，而不定義具名函式 incrementmul，如下所示：In the previous examples, instead of defining named functions increment and mul, you could use lambda expressions as follows:

let result3 = apply1 (fun x -> x + 1) 100

let result4 = apply2 (fun x y -> x * y ) 10 20

## 函式組合和管線Function Composition and Pipelining

F# 中的函式可以從其他函式組合。Functions in F# can be composed from other functions. 兩個函式 function1function2 會組合成另一個函式，表示先套用 function1，接著套用 function2The composition of two functions function1 and function2 is another function that represents the application of function1 followed the application of function2:

let function1 x = x + 1
let function2 x = x * 2
let h = function1 >> function2
let result5 = h 100

let result = 100 |> function1 |> function2

// Function composition and pipeline operators compared.

let addOne x = x + 1
let timesTwo x = 2 * x

// Composition operator
// ( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
let Compose2 = addOne >> timesTwo

// Backward composition operator
// ( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
let Compose1 = addOne << timesTwo

// Result is 5
let result1 = Compose1 2

// Result is 6
let result2 = Compose2 2

// Pipelining
// Pipeline operator
// ( |> ) : 'T1 -> ('T1 -> 'U) -> 'U
let Pipeline2 x = addOne x |> timesTwo

// Backward pipeline operator
// ( <| ) : ('T -> 'U) -> 'T -> 'U
let Pipeline1 x = addOne <| timesTwo x

// Result is 5
let result3 = Pipeline1 2

// Result is 6
let result4 = Pipeline2 2