📅  最后修改于: 2020-11-21 06:37:58             🧑  作者: Mango
在F#中,函数的工作方式类似于数据类型。您可以像其他变量一样声明和使用函数。
由于函数可以像其他任何变量一样使用,因此您可以-
通过使用let关键字定义函数。函数定义具有以下语法-
let [inline] function-name parameter-list [ : return-type ]
= function-body
哪里,
function-name是代表函数的标识符。
parameter-list提供用空格分隔的参数列表。您还可以为每个参数指定一个显式类型,如果未指定,则编译器倾向于从函数体中推断出该类型(如变量)。
函数体由一个表达式组成,或者由多个表达式组成的复合表达式。函数主体中的最后一个表达式是返回值。
return-type是冒号,后跟一个类型,并且是可选的。如果未指定返回类型,则编译器根据函数主体中的最终表达式确定返回类型。
您可以在函数名称之后列出参数的名称。您可以指定参数的类型。参数的类型应遵循用冒号分隔的参数名称。
如果未指定任何参数类型,则由编译器推断出来。
例如-
let doubleIt (x : int) = 2 * x
通过指定函数名称,后跟一个空格,然后指定任何由空格分隔的参数,来调用一个函数。
例如-
let vol = cylinderVolume 3.0 5.0
以下程序说明了这些概念。
以下程序在给出半径和长度作为参数时计算圆柱体的体积
// 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
以下程序返回两个给定参数的较大值-
// 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
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返回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
以下程序返回阶乘8-
open System
let rec fact x =
if x < 1 then 1
else x * fact (x - 1)
Console.WriteLine(fact 8)
编译并执行程序时,将产生以下输出-
40320
F#使用链接的箭头符号报告有关函数和值中的数据类型的信息。让我们以一个接受一个int输入并返回字符串的函数为例。用箭头表示,它写为-
int -> string
从左到右读取数据类型。
让我们采用另一个假设函数,该函数接受两个int数据输入并返回一个字符串。
let mydivfunction x y = (x / y).ToString();;
F#使用链接的箭头符号将数据类型报告为-
val mydivfunction : x:int -> y:int -> string
返回类型由最右边的数据类型以链接箭头表示。
一些更多的例子-
Notation | Meaning |
---|---|
float → float → float | The function takes two float inputs, returns another float. |
int → string → float | The function takes an int and a string input, returns a float. |
Lambda表达式是一个未命名的函数。
让我们以两个功能为例-
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,可以将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
编译并执行程序时,将产生以下输出-
35
在F#中,一个函数可以由其他功能组成。
下面的示例示出了函数名为f的组合物,从两个函数功能1和功能2 –
let function1 x = x + 1
let function2 x = x * 5
let f = function1 >> function2
let res = f 10
printfn "%d" res
编译并执行程序时,将产生以下输出-
55
F#还提供了一个称为函数流水线的功能。流水线化允许将函数调用作为后续操作链接在一起。
以下示例显示-
let function1 x = x + 1
let function2 x = x * 5
let res = 10 |> function1 |> function2
printfn "%d" res
编译并执行程序时,将产生以下输出-
55