La coincidència de patrons és una característica poderosa i essencial en F#. Permet descompondre estructures de dades complexes i prendre decisions basades en la forma i el contingut d'aquestes estructures. En aquest tema, explorarem com utilitzar la coincidència de patrons per simplificar el codi i fer-lo més llegible i mantenible.
Conceptes Clau
- Patrons Bàsics: Coincidència de valors literals, variables i comodins.
- Patrons Complexos: Coincidència de tuples, llistes i unions discriminades.
- Patrons amb Guàrdies: Afegir condicions addicionals als patrons.
- Patrons Actius: Definir patrons personalitzats per a coincidències més avançades.
- Patrons Bàsics
Coincidència de Valors Literals
let describeNumber x = match x with | 1 -> "One" | 2 -> "Two" | _ -> "Other" printfn "%s" (describeNumber 1) // Output: One printfn "%s" (describeNumber 3) // Output: Other
Coincidència de Variables i Comodins
let describeOption opt = match opt with | Some value -> sprintf "Value is %d" value | None -> "No value" printfn "%s" (describeOption (Some 42)) // Output: Value is 42 printfn "%s" (describeOption None) // Output: No value
- Patrons Complexos
Coincidència de Tuples
let describeTuple t = match t with | (1, "one") -> "Tuple with 1 and 'one'" | (2, "two") -> "Tuple with 2 and 'two'" | _ -> "Other tuple" printfn "%s" (describeTuple (1, "one")) // Output: Tuple with 1 and 'one' printfn "%s" (describeTuple (3, "three")) // Output: Other tuple
Coincidència de Llistes
let describeList lst = match lst with | [] -> "Empty list" | [x] -> sprintf "Single element: %d" x | [x; y] -> sprintf "Two elements: %d and %d" x y | _ -> "A longer list" printfn "%s" (describeList []) // Output: Empty list printfn "%s" (describeList [1]) // Output: Single element: 1 printfn "%s" (describeList [1; 2]) // Output: Two elements: 1 and 2 printfn "%s" (describeList [1; 2; 3]) // Output: A longer list
Coincidència d'Unions Discriminades
type Shape = | Circle of radius: float | Rectangle of width: float * height: float let describeShape shape = match shape with | Circle radius -> sprintf "Circle with radius %f" radius | Rectangle (width, height) -> sprintf "Rectangle with width %f and height %f" width height let circle = Circle 5.0 let rectangle = Rectangle (4.0, 6.0) printfn "%s" (describeShape circle) // Output: Circle with radius 5.000000 printfn "%s" (describeShape rectangle) // Output: Rectangle with width 4.000000 and height 6.000000
- Patrons amb Guàrdies
let describeNumberWithGuard x = match x with | n when n > 0 -> "Positive number" | n when n < 0 -> "Negative number" | _ -> "Zero" printfn "%s" (describeNumberWithGuard 5) // Output: Positive number printfn "%s" (describeNumberWithGuard -3) // Output: Negative number printfn "%s" (describeNumberWithGuard 0) // Output: Zero
- Patrons Actius
Els patrons actius permeten definir patrons personalitzats que poden encapsular lògica complexa de coincidència.
let (|Even|Odd|) x = if x % 2 = 0 then Even else Odd let describeNumberWithActivePattern x = match x with | Even -> "Even number" | Odd -> "Odd number" printfn "%s" (describeNumberWithActivePattern 4) // Output: Even number printfn "%s" (describeNumberWithActivePattern 7) // Output: Odd number
Exercicis Pràctics
Exercici 1: Coincidència de Patrons Bàsics
Escriu una funció describeDay
que prengui un enter representant un dia de la setmana (1 per dilluns, 2 per dimarts, etc.) i retorni el nom del dia. Si el valor no està entre 1 i 7, retorna "Invalid day".
let describeDay day = match day with | 1 -> "Monday" | 2 -> "Tuesday" | 3 -> "Wednesday" | 4 -> "Thursday" | 5 -> "Friday" | 6 -> "Saturday" | 7 -> "Sunday" | _ -> "Invalid day" // Prova la funció printfn "%s" (describeDay 1) // Output: Monday printfn "%s" (describeDay 8) // Output: Invalid day
Exercici 2: Coincidència de Llistes
Escriu una funció sumFirstTwo
que sumi els dos primers elements d'una llista d'enters. Si la llista té menys de dos elements, retorna 0.
let sumFirstTwo lst = match lst with | [x; y] -> x + y | _ -> 0 // Prova la funció printfn "%d" (sumFirstTwo [1; 2; 3]) // Output: 3 printfn "%d" (sumFirstTwo [1]) // Output: 0
Exercici 3: Coincidència d'Unions Discriminades
Defineix una unió discriminada TrafficLight
amb els valors Red
, Yellow
i Green
. Escriu una funció nextLight
que prengui un valor de TrafficLight
i retorni el següent color en la seqüència (Red -> Green, Green -> Yellow, Yellow -> Red).
type TrafficLight = | Red | Yellow | Green let nextLight light = match light with | Red -> Green | Green -> Yellow | Yellow -> Red // Prova la funció printfn "%A" (nextLight Red) // Output: Green printfn "%A" (nextLight Green) // Output: Yellow printfn "%A" (nextLight Yellow) // Output: Red
Conclusió
La coincidència de patrons en F# és una eina poderosa que permet escriure codi més clar i concís. Hem vist com utilitzar patrons bàsics, complexos, amb guàrdies i actius per descompondre i processar dades de manera eficient. Practicar aquests conceptes amb exercicis pràctics ajudarà a consolidar el teu coneixement i habilitats en F#. En el següent mòdul, explorarem les col·leccions en F# i com treballar amb elles de manera eficient.
Curs de Programació en F#
Mòdul 1: Introducció a F#
Mòdul 2: Conceptes Bàsics
- Tipus de Dades i Variables
- Funcions i Immutabilitat
- Coincidència de Patrons
- Col·leccions: Llistes, Matrius i Seqüències
Mòdul 3: Programació Funcional
Mòdul 4: Estructures de Dades Avançades
Mòdul 5: Programació Orientada a Objectes en F#
- Classes i Objectes
- Herència i Interfícies
- Barreja de Programació Funcional i Orientada a Objectes
- Mòduls i Espais de Noms
Mòdul 6: Programació Asíncrona i Paral·lela
- Fluxos de Treball Asíncrons
- Biblioteca de Tasques Paral·leles
- MailboxProcessor i Agents
- Patrons de Concurrència
Mòdul 7: Accés i Manipulació de Dades
Mòdul 8: Proves i Depuració
- Proves Unitàries amb NUnit
- Proves Basades en Propietats amb FsCheck
- Tècniques de Depuració
- Perfilat de Rendiment