Tracks
/
Elm
Elm
/
Ejercicios
/
¡Su boleto, por favor!
¡Su boleto, por favor!

¡Su boleto, por favor!

Ejercicio de aprendizaje

Introducción

Coincidencia de patrones

La coincidencia de patrones permite escribir código con ramificaciones expresivas, y la desestructuración aporta una forma elegante de vincular valores a variables.

Coincidencia de patrones simple

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!"

Desestructuración

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

Instrucciones

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.

1. Detecta los comentarios vacíos

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

2. Cuenta la cantidad de comentarios del creador

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

3. Detecta los tickets asignados al equipo de desarrollo

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

4. Asigna tickets a los empleados de TI

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!!" ) ]
--        }
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Elm Exercism

¿Todo listo para empezar ¡Su boleto, por favor!?

Regístrate en Exercism para aprender y dominar Elm con 28 conceptos110 ejercicios y mentoría humana real, todo gratis.