La coincidencia de patrones permite escribir código con ramificaciones expresivas, y la desestructuración aporta una forma elegante de vincular valores a variables.
La coincidencia de patrones puede vincular valores a variables, o descartarlos con el comodín _, usando la sentencia case.
type Entity = Alien | Stranger (Maybe String) | Friend { name: String }
hello : Entity -> String
hello entity =
case entity of
-- Custom type variant
Alien -> "Hello, you are not from around here are you?"
-- Binding to a litteral value nested in Stranger
Stranger (Just nametag) -> "Hello, erm... " ++ nametag ++ "."
-- Discarding Friend's data
Friend _ -> "Hi!"
-- All other cases
_ -> "Hello stranger!"
La desestructuración puede vincular valores en enlaces let, en argumentos de funciones y, por supuesto, en expresiones case, siempre que solo haya una forma posible para los datos.
pairSum : ( Int, Int ) -> Int
pairSum pair =
-- Destructuring of a pair in a 'let' binding
let ( x, y ) = pair
in x + y
-- Destructuring in the function argument
pairSum : ( Int, Int ) -> Int
pairSum ( x, y ) = x + y
-- Custom type containing a single variant
type Container = Box String
-- Destructuring in the function argument
unbox : Container -> String
unbox (Box str) = str
-- Destructuring combined with pattern matching
unboxMaybe : Maybe Container -> Maybe String
unboxMaybe maybeContainer =
case maybeContainer of
Nothing -> Nothing
Just (Box "42") -> Just "The answer to the universe!"
Just (Box str) -> Just str
La desestructuración también se puede usar con registros, o con la palabra clave as.
type alias Circle =
{ radius : Float
, center : ( Float, Float )
}
perimeter : Circle -> Float
perimeter { radius } =
2 * pi * radius
left : Circle -> Float
left { radius, center } =
-- the pair center cannot be pattern matched directly in the function argument
-- so we do it in a 'let' statement
let ( x, _ ) = center
in x - radius
-- using the 'as' keyword to bind both the fields and the whole record
smaller : Float -> Circle -> Circle
smaller reduction ({ radius } as circle) =
if reduction < radius then
{ circle | radius = radius - reduction }
else
circle
Eres parte de la mesa de ayuda de TI y quieres mejorar el sistema de tickets para que sea más eficiente y proporcionar estadísticas a tu gerente.
Un ticket tiene un estado (nuevo, en progreso...), un creador (identificado por un nombre de usuario y un ID de empleado), se puede asignar a un empleado de TI y contiene un historial de comentarios.
Aquí tienes cuatro tareas que mejorarán tu sistema de tickets actual.
Los comentarios vacíos saturan la interfaz y no aportan información, así que quieres filtrarlos.
Define una función auxiliar emptyComment que recibe un par usuario/comentario y devuelve True para los comentarios vacíos.
Usa la desestructuración para extraer el usuario y el comentario directamente en el argumento de la función. Ignora el usuario, ya que no necesitas esa información.
emptyComment ( User "Alice", "" )
-- => True
Tu gerente quiere tener estadísticas sobre la participación de los usuarios en el proceso de tickets. Te pide que revises cuántos comentarios agrega el creador del ticket.
Define numberOfCreatorComments, que recibe un ticket y devuelve la cantidad de comentarios que agregó el creador del ticket.
Usa la desestructuración en el argumento de la función para extraer el registro del tipo Ticket, al mismo tiempo que los campos que necesitas del registro.
Luego, desestructura el createdBy en un enlace let para que puedas contar los comentarios relevantes.
Usa las funciones de List para hacer el conteo y usa la desestructuración en el argumento de la función de una función anónima para separar el par usuario/comentario.
numberOfCreatorComments
numberOfCreatorComments
(Ticket
{ status = Closed
, createdBy = ( User "Chiaki", 1 )
, assignedTo = Nothing
, comments = [ ( User "Chiaki", "Never mind, fixed it." ) ]
}
)
-- => 1
Algunos tickets se tienen que escalar a Alice, Bob o Charlie, del equipo de desarrollo. Es importante estar pendiente de esos tickets para asegurarte de que avanzan.
Define una función auxiliar assignedToDevTeam que comprueba si un ticket está asignado a uno de los miembros del equipo de desarrollo.
Usa la desestructuración en el argumento de la función para extraer el registro del tipo Ticket, así como el campo que necesitas.
Luego, usa una sola sentencia case para comprobar si el ticket está asignado a Alice, Bob o Charlie, usando coincidencia de patrones recursiva para extraer sus nombres de usuario y coincidencia de patrones literal para hacerlos coincidir.
assignedToDevTeam
(Ticket
{ status = InProgress
, createdBy = ( User "Bill", 2 )
, assignedTo = Just (User "Alice")
, comments = [ ( User "Bill", "What's an 'undefined'?" ) ]
}
)
-- => True
A veces hay un montón de tickets que se deben reasignar a otros empleados de TI.
Define una función assignTicketTo que te ayude a hacerlo. La función recibe dos argumentos: un usuario al que asignar el ticket y un ticket.
Si el estado del ticket es New, asígnalo al nuevo usuario y cambia el estado a InProgress.
Para los demás estados, simplemente reasigna el ticket a los nuevos usuarios, excepto los tickets con el estado Archived, que no se deben modificar en absoluto.
Usa la desestructuración en el argumento de la función para extraer el registro del tipo Ticket, así como el campo que necesitas, y también usa la palabra clave as para capturar el registro completo tal como está.
Usa una sola sentencia case para hacer coincidir el estado y devolver el ticket adecuado, creado a partir de modificar el registro original que capturaste con la palabra clave as.
assignTicketTo (User "Danny")
(Ticket
{ status = New
, createdBy = ( User "Jesse", 3 )
, assignedTo = Just (User "Alice")
, comments = [ ( User "Jesse", "I've been waiting for 6 months!!" ) ]
}
)
-- => Ticket
-- { status = InProgress
-- , createdBy = ( User "Jesse", 3 )
-- , assignedTo = Just (User "Danny")
-- , comments = [ ( User "Jesse", "I've been waiting for 6 months!!" ) ]
-- }
Regístrate en Exercism para aprender y dominar Elm con 28 conceptos110 ejercicios y mentoría humana real, todo gratis.