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

  1. Patrons Bàsics: Coincidència de valors literals, variables i comodins.
  2. Patrons Complexos: Coincidència de tuples, llistes i unions discriminades.
  3. Patrons amb Guàrdies: Afegir condicions addicionals als patrons.
  4. Patrons Actius: Definir patrons personalitzats per a coincidències més avançades.

  1. 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

  1. 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

  1. 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

  1. 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.

© Copyright 2024. Tots els drets reservats