F # - Funzioni

In F #, le funzioni funzionano come i tipi di dati. Puoi dichiarare e utilizzare una funzione allo stesso modo di qualsiasi altra variabile.

Poiché le funzioni possono essere utilizzate come qualsiasi altra variabile, puoi:

  • Crea una funzione, con un nome e associa quel nome a un tipo.
  • Assegnagli un valore.
  • Eseguire alcuni calcoli su quel valore.
  • Passalo come parametro a un'altra funzione o sottoprogramma.
  • Restituisce una funzione come risultato di un'altra funzione.

Definizione di una funzione

Le funzioni vengono definite utilizzando il letparola chiave. Una definizione di funzione ha la seguente sintassi:

let [inline] function-name parameter-list [ : return-type ]
   = function-body

Dove,

  • function-name è un identificatore che rappresenta la funzione.

  • parameter-listfornisce l'elenco dei parametri separati da spazi. Puoi anche specificare un tipo esplicito per ogni parametro e se non specificato il compilatore tende a dedurlo dal corpo della funzione (come le variabili).

  • function-bodyconsiste in un'espressione o un'espressione composta costituita da un numero di espressioni. L'espressione finale nel corpo della funzione è il valore restituito.

  • return-typeè un due punti seguito da un tipo ed è facoltativo. Se il tipo restituito non è specificato, il compilatore lo determina dall'espressione finale nel corpo della funzione.

Parametri di una funzione

Elenchi i nomi dei parametri subito dopo il nome della funzione. È possibile specificare il tipo di un parametro. Il tipo di parametro dovrebbe seguire il nome del parametro separato da due punti.

Se non viene specificato alcun tipo di parametro, viene dedotto dal compilatore.

Ad esempio:

let doubleIt (x : int) = 2 * x

Chiamare una funzione

Una funzione viene chiamata specificando il nome della funzione seguito da uno spazio e quindi qualsiasi argomento separato da spazi.

Ad esempio:

let vol = cylinderVolume 3.0 5.0

I seguenti programmi illustrano i concetti.

Esempio 1

Il seguente programma calcola il volume di un cilindro quando il raggio e la lunghezza sono dati come parametri

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

Quando compili ed esegui il programma, restituisce il seguente output:

Volume: 141.372

Esempio 2

Il seguente programma restituisce il valore maggiore di due parametri dati:

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

Quando compili ed esegui il programma, restituisce il seguente output:

Max Value: 52

Esempio 3

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

Quando compili ed esegui il programma, restituisce il seguente output:

Double 19: 38

Funzioni ricorsive

Le funzioni ricorsive sono funzioni che chiamano se stesse.

Puoi definire un ricorsivo usando il let rec combinazione di parole chiave.

La sintassi per definire una funzione ricorsiva è:

//Recursive function definition
let rec function-name parameter-list = recursive-function-body

Ad esempio:

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

Esempio 1

Il seguente programma restituisce Fibonacci da 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)

Quando compili ed esegui il programma, restituisce il seguente output:

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

Esempio 2

Il seguente programma restituisce il fattoriale 8 -

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

Quando compili ed esegui il programma, restituisce il seguente output:

40320

Notazioni freccia in F #

F # segnala il tipo di dati in funzioni e valori, usando una notazione a freccia concatenata. Prendiamo un esempio di una funzione che accetta un input int e restituisce una stringa. Nella notazione a freccia, è scritto come -

int -> string

I tipi di dati vengono letti da sinistra a destra.

Prendiamo un'altra ipotetica funzione che accetta due input di dati int e restituisce una stringa.

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

F # segnala il tipo di dati utilizzando la notazione a freccia concatenata come -

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

Il tipo restituito è rappresentato dal tipo di dati più a destra in notazione a freccia concatenata.

Alcuni altri esempi -

Notazione Senso
float → float → float La funzione accetta due ingressi float , restituisce un altro float .
int → stringa → float La funzione accetta un int e una stringa di input, restituisce un float .

Espressioni lambda

UN lambda expression è una funzione senza nome.

Facciamo un esempio di due funzioni:

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

Quando compili ed esegui il programma, restituisce il seguente output:

35

Ora nell'esempio sopra, se invece di definire la funzione mul, avremmo potuto usare espressioni lambda come -

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

Quando compili ed esegui il programma, restituisce il seguente output:

35

Composizione delle funzioni e pipelining

In F #, una funzione può essere composta da altre funzioni.

L'esempio seguente mostra la composizione di una funzione denominata f, da due funzioni function1 e function2 -

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

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

Quando compili ed esegui il programma, restituisce il seguente output:

55

F # fornisce anche una funzionalità chiamata pipelining of functions. Il pipelining consente alle chiamate di funzione di essere concatenate insieme come operazioni successive.

L'esempio seguente mostra che:

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

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

Quando compili ed esegui il programma, restituisce il seguente output:

55