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: OtherCoincidè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 tupleCoincidè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 listCoincidè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 numberExercicis 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 dayExercici 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: 0Exercici 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: RedConclusió
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
