📜  F#-函数

📅  最后修改于: 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

以下程序说明了这些概念。

例子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

以下程序将斐波那契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

返回类型由最右边的数据类型以链接箭头表示。

一些更多的例子-

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表达式

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