F # - Correspondance de motif

La correspondance de modèles vous permet de «comparer des données avec une ou plusieurs structures logiques, de décomposer les données en parties constituantes ou d'extraire des informations à partir de données de diverses manières».

En d'autres termes, il offre un moyen plus flexible et plus puissant de tester les données par rapport à une série de conditions et d'effectuer certains calculs en fonction de la condition remplie.

Conceptuellement, c'est comme une série d'énoncés si… alors.

Syntaxe

En termes généraux, la correspondance de modèles suit cette syntaxe en F # -

match expr with
| pat1 - result1
| pat2 -> result2
| pat3 when expr2 -> result3
| _ -> defaultResult

Où,

  • Chacun | symbole définit une condition.
  • Le symbole -> signifie "si la condition est vraie, renvoyer cette valeur ...".
  • Le symbole _ fournit le modèle par défaut, ce qui signifie qu'il correspond à toutes les autres choses comme un caractère générique.

Exemple 1

L'exemple suivant calcule les nombres de Fibonacci à l'aide de la syntaxe de correspondance de modèle -

let rec fib n =
   match n with
   | 0 -> 0
   | 1 -> 1
   | _ -> fib (n - 1) + fib (n - 2)
for i = 1 to 10 do
   printfn "Fibonacci %d: %d" i (fib i)

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

Fibonacci 1: 1
Fibonacci 2: 1
Fibonacci 3: 2
Fibonacci 4: 3
Fibonacci 5: 5
Fibonacci 6: 8
Fibonacci 7: 13
Fibonacci 8: 21
Fibonacci 9: 34
Fibonacci 10: 55

Vous pouvez également enchaîner plusieurs conditions, qui renvoient la même valeur. Par exemple -

Exemple 2

let printSeason month =
   match month with
   | "December" | "January" | "February" -> printfn "Winter"
   | "March" | "April" -> printfn "Spring"
   | "May" | "June" -> printfn "Summer"
   | "July" | "August" -> printfn "Rainy"
   | "September" | "October" | "November" -> printfn "Autumn"
   | _ -> printfn "Season depends on month!"

printSeason "February"
printSeason "April"
printSeason "November"
printSeason "July"

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

Winter
Spring
Autumn
Rainy

Fonctions de correspondance de modèles

F # vous permet d'écrire des fonctions de correspondance de motifs en utilisant function mot-clé -

let getRate = function
   | "potato" -> 10.00
   | "brinjal" -> 20.50
   | "cauliflower" -> 21.00
   | "cabbage" -> 8.75
   | "carrot" -> 15.00
   | _ -> nan (* nan is a special value meaning "not a number" *)

printfn "%g"(getRate "potato")
printfn "%g"(getRate "brinjal")
printfn "%g"(getRate "cauliflower")
printfn "%g"(getRate "cabbage")
printfn "%g"(getRate "carrot")

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

10
20.5
21
8.75
15

Ajout de filtres ou de gardes aux modèles

Vous pouvez ajouter des filtres ou des gardes aux motifs à l'aide de when mot-clé.

Exemple 1

let sign = function
   | 0 -> 0
   | x when x < 0 -> -1
   | x when x > 0 -> 1

printfn "%d" (sign -20)
printfn "%d" (sign 20)
printfn "%d" (sign 0)

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

-1
1
0

Exemple 2

let compareInt x =
   match x with
   | (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2
   | (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2
   | (var1, var2) -> printfn "%d equals %d" var1 var2

compareInt (11,25)
compareInt (72, 10)
compareInt (0, 0)

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

11 is less than 25
72 is greater than 10
0 equals 0

Correspondance de motifs avec des tuples

L'exemple suivant montre la correspondance de modèle avec les tuples -

let greeting (name, subject) =
   match (name, subject) with
   | ("Zara", _) -> "Hello, Zara"
   | (name, "English") -> "Hello, " + name + " from the department of English"
   | (name, _) when subject.StartsWith("Comp") -> "Hello, " + name + " from the department of Computer Sc."
   | (_, "Accounts and Finance") -> "Welcome to the department of Accounts and Finance!"
   | _ -> "You are not registered into the system"

printfn "%s" (greeting ("Zara", "English"))
printfn "%s" (greeting ("Raman", "Computer Science"))
printfn "%s" (greeting ("Ravi", "Mathematics"))

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

Hello, Zara
Hello, Raman from the department of Computer Sc.
You are not registered into the system

Correspondance de modèles avec des enregistrements

L'exemple suivant illustre la mise en correspondance de modèles avec des enregistrements -

type Point = { x: float; y: float }
let evaluatePoint (point: Point) =
   match point with
   | { x = 0.0; y = 0.0 } -> printfn "Point is at the origin."
   | { x = xVal; y = 0.0 } -> printfn "Point is on the x-axis. Value is %f." xVal
   | { x = 0.0; y = yVal } -> printfn "Point is on the y-axis. Value is %f." yVal
   | { x = xVal; y = yVal } -> printfn "Point is at (%f, %f)." xVal yVal

evaluatePoint { x = 0.0; y = 0.0 }
evaluatePoint { x = 10.0; y = 0.0 }
evaluatePoint { x = 0.0; y = 10.0 }
evaluatePoint { x = 10.0; y = 10.0 }

Lorsque vous compilez et exécutez le programme, il produit la sortie suivante -

Point is at the origin.
Point is on the x-axis. Value is 10.000000.
Point is on the y-axis. Value is 10.000000.
Point is at (10.000000, 10.000000).