F # - Funciones
En F #, las funciones funcionan como tipos de datos. Puede declarar y utilizar una función de la misma forma que cualquier otra variable.
Dado que las funciones se pueden usar como cualquier otra variable, puede:
- Cree una función, con un nombre y asocie ese nombre con un tipo.
- Asígnele un valor.
- Realice algún cálculo sobre ese valor.
- Pasarlo como parámetro a otra función o subrutina.
- Devuelve una función como resultado de otra función.
Definición de una función
Las funciones se definen utilizando el letpalabra clave. Una definición de función tiene la siguiente sintaxis:
let [inline] function-name parameter-list [ : return-type ]
= function-body
Dónde,
function-name es un identificador que representa la función.
parameter-listda la lista de parámetros separados por espacios. También puede especificar un tipo explícito para cada parámetro y, si no se especifica, el compilador tiende a deducirlo del cuerpo de la función (como las variables).
function-bodyconsta de una expresión o una expresión compuesta que consta de varias expresiones. La expresión final en el cuerpo de la función es el valor de retorno.
return-typeson dos puntos seguidos de un tipo y es opcional. Si no se especifica el tipo de retorno, el compilador lo determina a partir de la expresión final en el cuerpo de la función.
Parámetros de una función
Enumera los nombres de los parámetros justo después del nombre de la función. Puede especificar el tipo de parámetro. El tipo de parámetro debe seguir al nombre del parámetro separado por dos puntos.
Si no se especifica ningún tipo de parámetro, el compilador lo infiere.
Por ejemplo
let doubleIt (x : int) = 2 * x
Llamar a una función
Se llama a una función especificando el nombre de la función seguido de un espacio y luego cualquier argumento separado por espacios.
Por ejemplo
let vol = cylinderVolume 3.0 5.0
Los siguientes programas ilustran los conceptos.
Ejemplo 1
El siguiente programa calcula el volumen de un cilindro cuando el radio y la longitud se dan como parámetros
// 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
Cuando compila y ejecuta el programa, produce el siguiente resultado:
Volume: 141.372
Ejemplo 2
El siguiente programa devuelve el valor mayor de dos parámetros dados:
// 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
Cuando compila y ejecuta el programa, produce el siguiente resultado:
Max Value: 52
Ejemplo 3
let doubleIt (x : int) = 2 * x
printfn "Double 19: %d" ( doubleIt(19))
Cuando compila y ejecuta el programa, produce el siguiente resultado:
Double 19: 38
Funciones recursivas
Las funciones recursivas son funciones que se llaman a sí mismas.
Usted define un recursivo usando el let rec combinación de palabras clave.
La sintaxis para definir una función recursiva es:
//Recursive function definition
let rec function-name parameter-list = recursive-function-body
Por ejemplo
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
Ejemplo 1
El siguiente programa devuelve Fibonacci 1 a 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)
Cuando compila y ejecuta el programa, produce el siguiente resultado:
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
Ejemplo 2
El siguiente programa devuelve factorial 8 -
open System
let rec fact x =
if x < 1 then 1
else x * fact (x - 1)
Console.WriteLine(fact 8)
Cuando compila y ejecuta el programa, produce el siguiente resultado:
40320
Notaciones de flecha en F #
F # informa sobre el tipo de datos en funciones y valores, utilizando una notación de flecha encadenada. Tomemos un ejemplo de una función que toma una entrada int y devuelve una cadena. En notación de flechas, se escribe como:
int -> string
Los tipos de datos se leen de izquierda a derecha.
Tomemos otra función hipotética que toma dos entradas de datos int y devuelve una cadena.
let mydivfunction x y = (x / y).ToString();;
F # informa el tipo de datos usando notación de flecha encadenada como -
val mydivfunction : x:int -> y:int -> string
El tipo de retorno está representado por el tipo de datos más a la derecha en notación de flecha encadenada.
Algunos ejemplos más:
Notación | Sentido |
---|---|
flotar → flotar → flotar | La función toma dos entradas flotantes , devuelve otra flotante . |
int → cadena → flotar | La función toma un int y una entrada de cadena , devuelve un float . |
Expresiones lambda
UN lambda expression es una función sin nombre.
Tomemos un ejemplo de dos funciones:
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
Cuando compila y ejecuta el programa, produce el siguiente resultado:
35
Ahora, en el ejemplo anterior, si en lugar de definir la función mul, podríamos haber usado expresiones lambda como -
let applyFunction ( f: int -> int -> int) x y = f x y
let res = applyFunction (fun x y -> x * y ) 5 7
printfn "%d" res
Cuando compila y ejecuta el programa, produce el siguiente resultado:
35
Composición de funciones y canalización
En F #, una función puede estar compuesta por otras funciones.
El siguiente ejemplo muestra la composición de una función llamada f, a partir de dos funciones function1 y function2 -
let function1 x = x + 1
let function2 x = x * 5
let f = function1 >> function2
let res = f 10
printfn "%d" res
Cuando compila y ejecuta el programa, produce el siguiente resultado:
55
F # también proporciona una función llamada pipelining of functions. La canalización permite encadenar las llamadas a funciones como operaciones sucesivas.
El siguiente ejemplo muestra que:
let function1 x = x + 1
let function2 x = x * 5
let res = 10 |> function1 |> function2
printfn "%d" res
Cuando compila y ejecuta el programa, produce el siguiente resultado:
55